Межсайтовое выполнение сценариев (англ. Сross Site Sсriрting или XSS) — атака на веб-сайты, заключаюшаяся во внедрении в документ вредоносного кода, который будет выполнен в браузере жертвы. Специфика подобных атак заключается в том, что вредоносный код может использовать авторизацию пользователя в веб-системе для получения к ней расширенного доступа или для получения авторизационных данных пользователя. Это может быть достигнуто путём взаимодействия внедрённого кода с веб-сервером злоумышленника.

Классификация XSS

Межсайтовое выполнение сценариев принято классифицировать по двум критериям: вектору и способу воздействия. По вектору воздействия XSS делится на:

  • отражённую (англ. reflected) — возвращаемую сервером в ответ на тот же запрос, в котором был передан вредоносный код;
  • устойчивую (англ. stored) — сохраняемую на сервере и доступную во всех ответах на один и тот же запрос, не содержащий вредоносного кода;
  • основанную на объектной модели документа (англ. DOM-based) — проведение которой возможно без отправки каких-либо запросов на сервер.
По способу воздействия XSS может быть:
  • активная — не требующая каких-либо лишних действий со стороны пользователя с точки зрения функционала веб-приложения;
  • пассивная — срабатывающая при выполнении пользователем определённого действия (клик или наведение указателя мыши и т.п.)

Отражённая XSS возникает в случае, когда переданные в запросе данные используются сервером для генерации страницы без надлежащей обработки. Это позволяет злоумышленнику передать вредоносный код, который будет внедрён в документ, например в одном из параметров запроса GET. При переходе по такой ссылке, вредоносный код будет выполнен в контексте текущего пользователя веб-системы, т.е. он может получить доступ к авторизационным данным пользователя в идентификаторах Cookie или совершать запросы от лица авторизованного пользователя.

К примеру, приведённый ниже код на языке PHP пытается получить страницу с информацией о пользователе, имя которого передано в параметре username:

$username = $_GET['username'];
$result = mysql_query("SELECT * FROM users WHERE username = '$username'");
if (mysql_num_rows($result) == 0) {
	print "Пользователь '$username' не найден!";
} else {
	// Вывод информации о пользователе…
}

Поскольку значение параметра username никак не обрабатывается перед выводом, существует возможность передать в нём HTML-код, например <script>alert('XSS')</script>. Этот код будет внедрён в ответ сервера и вредоносный сценарий на языке JavaScript будет выполнен браузером в контексте уязвимого веб-приложения.

Важно отметить, что вредоносный код для внедрения в документ необходимо передавать при каждом запросе к серверу. Это позволяет обнаружить атаку такого типа как на стороне клиента (путём тщательного рассмотрения адресной строки браузера), так и на стороне сервера при помощи межсетевых экранов уровня приложения (WAF).

Типовой сценарий реализации отражённой XSS представлен на рисунке.

  1. Злоумышленник подготавливает URL, содержащий вредоносный код, и передаёт его жертве.
  2. Жертва переходит по полученному URL.
  3. Уязвимый веб-сайт включает вредоносный код из URL в документ и выдаёт его пользователю.
  4. Браузер жертвы выполняет вредоносный сценарий и передаёт авторизационные данные на сервер злоумышленника.

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

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

Типовой сценарий реализации устойчивой XSS представлен на рисунке.

  1. Злоумышленник использует одну из форм веб-сайта для сохранения вредоносного кода на сервере.
  2. Жертва производит запрос к веб-странице.
  3. Уязвимый веб-сайт включает вредоносный код из хранилища в документ и выдаёт его пользователю.
  4. Браузер жертвы выполняет вредоносный сценарий и передаёт авторизационные данные на сервер злоумышленника.

XSS, основанная на объектной модели документа, использует уязвимости клиентской части веб-приложения. К примеру, если сценарий JavaScript имеет доступ к параметру URL и формирует HTML-код на странице, используя эту информацию, при этом не обрабатывая её надлежащим образом, то возможно внедрить в документ вредоносный код, изменив соответствующий параметр URL.

Типовой сценарий реализации XSS, основанной на объектной модели документа, представлен на рисунке.

  1. Злоумышленник подготавливает URL, содержащий вредоносный код, и передаёт его жертве.
  2. Жертва переходит по полученному URL.
  3. Уязвимый веб-сайт обрабатывает запрос, но не включает вредоносный код в документ.
  4. Браузер жертвы выполняет сценарии клиентской части веб-сайта, которые модифицируют документ, включая в него вредоносный код из URL.
  5. Браузер жертвы выполняет вредоносный сценарий и передаёт авторизационные данные на сервер злоумышленника.

Предотвращение XSS

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

Для экранирования данных в языке PHP применяет функция htmlspecialchars(). Она приводит все небезопасные элементы к безопасным HTML-эквивалентам. Например, символ < заменяется на &lt;, а уже браузер преобразует эту последовательность обратно к символу угловой скобки.

Кодировка UTF-7

UTF-7 допускает несколько представлений для одной и той же строки. В частности, альтернативные представления допускаются для символов ASCII. В результате, если процедуры экранирования и проверки проводятся над строкой, которая впоследствии может быть интерпретирована как строка в кодировке UTF-7, альтернативные варианты кодирования могут быть использованы для обхода этих процедур.

В случае, если тег <title> расположен до тега <meta>, устанавливающего кодировку страницы, и заполняется пользовательскими данными, злоумышленник может вставить вредоносный код в кодировке UTF-7, обойдя таким образом фильтрацию таких символов, как <, > и ".

Для предотвращения подобных проблем приложения должны проводить проверки после декодирования строк и не пытаться автоматически использовать кодировку UTF-7.

HTML5 запрещает поддержку браузерами кодировки UTF-7 как потенциально опасной. Из современных браузеров эта уязвимость актуальна только для Internet Explorer.

Дополнительные материалы

  1. DOM XSS Wiki
  2. UTF-7 XSS Cheat Sheet
  3. XSS Cheat Sheet Calculator