(XSS contexts) Контексты межсайтового скриптинга

При тестировании отраженного и хранимого XSS ключевая задача — определить контекст XSS:

  • Местоположение внутри ответа, где появляются данные, контролируемые атакующим.

  • Любая проверка ввода или иная обработка, которую приложение применяет к этим данным.

Исходя из этих деталей, вы можете выбрать один или несколько кандидатных XSS-пейлоадов и проверить, являются ли они эффективными.

Note

Мы создали полноценный XSS cheat sheet, чтобы помочь в тестировании веб‑приложений и фильтров. Вы можете фильтровать по событиям и тегам и видеть, какие векторы требуют взаимодействия с пользователем. В шпаргалке также есть обходы песочницы AngularJS и многие другие разделы для исследований XSS.

XSS между HTML‑тегами

Когда контекст XSS — это текст между HTML‑тегами, вам нужно внедрить новые HTML‑теги, рассчитанные на запуск JavaScript.

Некоторые полезные способы выполнить JavaScript:

<script>alert(document.domain)</script>
<img src=1 onerror=alert(1)>

XSS в атрибутах HTML‑тега

Когда контекст XSS — внутри значения атрибута HTML‑тега, иногда можно завершить значение атрибута, закрыть тег и внедрить новый. Например:

Чаще в такой ситуации угловые скобки блокируются или кодируются, и ваш ввод не может вырваться из тега, в котором он находится. Если удаётся завершить значение атрибута, обычно можно добавить новый атрибут, создающий скриптуемый контекст, например обработчик события. Например:

Вышеуказанный пейлоад создаёт событие onfocus, которое выполнит JavaScript, когда элемент получит фокус, а также добавляет атрибут autofocus, чтобы попытаться автоматически триггерить onfocus без взаимодействия с пользователем. Наконец, он добавляет x=" для аккуратного восстановления последующей разметки.

Иногда контекст XSS — это тип атрибута HTML‑тега, который сам по себе может создавать скриптуемый контекст. В таком случае можно выполнить JavaScript, не завершая значение атрибута. Например, если контекст XSS — в атрибуте href тега anchor, вы можете использовать псевдопротокол javascript для выполнения скрипта. Например:

Вы можете столкнуться с сайтами, которые кодируют угловые скобки, но всё же позволяют инжектировать атрибуты. Иногда такие инъекции возможны даже внутри тегов, которые обычно не инициируют события автоматически, например в теге canonical. Вы можете эксплуатировать это поведение с помощью access keys и взаимодействия пользователя в Chrome. Access keys позволяют назначать горячие клавиши, ссылающиеся на конкретный элемент. Атрибут accesskey позволяет определить букву, которая при нажатии в комбинации с другими клавишами (они различаются на разных платформах) вызовет события. В следующей лабораторной вы можете поэкспериментировать с access keys и эксплуатировать тег canonical. Вы также можете эксплуатировать XSS в скрытых полях input с помощью техники, изобретённой PortSwigger Research.

XSS внутри JavaScript

Когда контекст XSS — это существующий JavaScript внутри ответа, возможен широкий спектр ситуаций, требующих разных техник для успешной эксплуатации.

Завершение существующего скрипта

В простейшем случае можно просто закрыть тег script, который охватывает существующий JavaScript, и внедрить новые HTML‑теги, запускающие выполнение JavaScript. Например, если контекст XSS следующий:

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

Причина, по которой это работает, состоит в том, что браузер сначала выполняет HTML‑разбор, чтобы определить элементы страницы, включая блоки скриптов, и только затем выполняет разбор JavaScript для понимания и выполнения внедрённых скриптов. Приведённый пейлоад оставляет исходный скрипт «сломленным» — с незавершённой строковой константой. Но это не мешает последующему скрипту быть разобранным и выполненным в обычном порядке.

Выход из строкового литерала JavaScript

В случаях, когда контекст XSS находится внутри заключённого в кавычки строкового литерала, часто можно вырваться из строки и выполнить JavaScript напрямую. Критически важно восстановить скрипт после места инъекции, поскольку любые синтаксические ошибки далее помешают выполнению всего скрипта.

Некоторые полезные способы вырваться из строкового литерала:

Некоторые приложения пытаются не допустить выхода из строкового литерала, экранируя любые одиночные кавычки обратной косой чертой. Обратная косая черта перед символом сообщает парсеру JavaScript, что символ следует трактовать буквально, а не как специальный (например, как терминатор строки). В такой ситуации приложения часто допускают ошибку, не экранируя сам символ обратной косой черты. Это означает, что атакующий может использовать собственную обратную косую черту, чтобы «обезвредить» обратную косую черту, добавленную приложением.

Например, предположим, что ввод:

преобразуется в:

Теперь вы можете использовать альтернативный пейлоад:

который преобразуется в:

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

Некоторые сайты усложняют XSS, ограничивая набор допустимых символов. Это может делаться на уровне сайта или посредством WAF, который не допускает ваши запросы до веб‑приложения. В таких ситуациях нужно экспериментировать с альтернативными способами вызова функций, обходящими эти меры безопасности. Один из способов — использовать оператор throw вместе с обработчиком исключений. Это позволяет передавать аргументы функции без использования круглых скобок. Следующий код присваивает функцию alert() глобальному обработчику исключений, а оператор throw передаёт 1 этому обработчику (в данном случае alert). В итоге функция alert() вызывается с аргументом 1.

Существует несколько способов использовать этот приём для вызова функций без скобок.

Следующая лабораторная демонстрирует сайт, который фильтрует некоторые символы. Чтобы решить её, вам придётся использовать техники, подобные описанным выше.

Использование HTML‑кодирования

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

Когда браузер разобрал HTML‑теги и атрибуты внутри ответа, он выполняет HTML‑декодирование значений атрибутов тегов до их дальнейшей обработки. Если серверное приложение блокирует или санитизирует некоторые символы, необходимые для успешной XSS‑эксплуатации, нередко можно обойти проверку, закодировав эти символы в HTML‑сущности.

Например, если контекст XSS следующий:

и приложение блокирует или экранирует одиночные кавычки, вы можете использовать такой пейлоад, чтобы вырваться из строкового литерала JavaScript и выполнить свой скрипт:

Последовательность &apos; — это HTML‑сущность, представляющая апостроф или одиночную кавычку. Поскольку браузер HTML‑декодирует значение атрибута onclick до интерпретации JavaScript, сущности декодируются в кавычки, которые становятся разделителями строк, и атака срабатывает.

XSS в шаблонных литералах JavaScript

Шаблонные литералы JavaScript — это строковые литералы, допускающие встраивание JavaScript‑выражений. Встроенные выражения вычисляются и обычно конкатенируются с окружающим текстом. Шаблонные литералы заключаются в обратные апострофы вместо обычных кавычек, а встроенные выражения обозначаются синтаксисом ${...}.

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

Когда контекст XSS — внутри шаблонного литерала JavaScript, нет необходимости завершать литерал. Вместо этого достаточно использовать синтаксис ${...}, чтобы встроить JavaScript‑выражение, которое будет выполнено при обработке литерала. Например, если контекст XSS следующий:

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

XSS через инъекцию клиентских шаблонов

Некоторые сайты используют клиентские шаблонные фреймворки, например AngularJS, для динамической отрисовки веб‑страниц. Если они внедряют пользовательский ввод в эти шаблоны небезопасным образом, атакующий может инжектировать собственные вредоносные выражения шаблонов, запускающие XSS‑атаку.

Last updated