Stored XSS

В этом разделе мы объясним, что такое Stored XSS, опишем последствия таких атак и расскажем, как находить уязвимости Stored XSS.

Что такое Stored XSS?

Stored XSS (также известный как second-order или persistent XSS) возникает, когда приложение получает данные из недоверенного источника и затем включает эти данные в своих последующих HTTP-ответах в небезопасной форме.

Предположим, что сайт позволяет пользователям оставлять комментарии к блог-постам, которые отображаются другим пользователям. Комментарии отправляются на сервер через HTTP-запрос такого вида:

POST /post/comment HTTP/1.1
Host: vulnerable-website.com
Content-Length: 100
postId=3&comment=This+post+was+extremely+helpful.&name=Carlos+Montoya&email=carlos%40normal-user.net

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

<p>This post was extremely helpful.</p>

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

<script>/* Bad stuff here... */</script>

В теле HTTP-запроса этот комментарий будет закодирован, например:

comment=%3Cscript%3E%2F*%2BBad%2Bstuff%2Bhere...%2B*%2F%3C%2Fscript%3E

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

<p><script>/* Bad stuff here... */</script></p>

Таким образом, вредоносный скрипт, предоставленный атакующим, выполнится в браузере жертвы в контексте её сессии с приложением.

Влияние атак сохранённого XSS

Если атакующий может контролировать скрипт, исполняемый в браузере жертвы, обычно он может полностью скомпрометировать этого пользователя. Атакующий может выполнить любые действия из списка, свойственного атакам через reflected xss, включая кражу данных, выполнение действий от имени пользователя и так далее.

С точки зрения эксплуатации, ключевое отличие между Reflected и Stored XSS заключается в том, что Stored XSS позволяет осуществлять полностью самодостаточные атаки непосредственно через приложение. Атакующему не нужно находить внешний механизм, чтобы заставить других пользователей отправлять особый запрос с его эксплойтом. Вместо этого он помещает вредоносный код в само приложение и просто ждёт, пока пользователи его встретят.

Stored XSS в различных контекстах

Существуют различные типы Stored XSS. Местоположение данных в ответе приложения определяет тип полезной нагрузки для эксплуатации уязвимости и может влиять на последствия.

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

Как находить и тестировать уязвимости Stored XSS

Ручное тестирование Stored XSS может быть затруднительным. Необходимо проверить все релевантные «входные точки», через которые данные, контролируемые атакующим, могут попасть в приложение, и все «выходные точки», где эти данные могут быть впоследствии выведены в ответах приложения.

Проверяем обязательно:

  • Параметры или другие данные внутри строки запроса URL и тела запроса.

  • Путь файла в URL.

  • HTTP-заголовки (для которых Reflected XSS обычно невозможно эксплуатировать).

  • Любые каналы (out-of-band routes), по которым атакующий может доставить данные в приложение. Конкретные каналы зависят исключительно от реализованного функционала приложения: например, веб-почтовое приложение будет обрабатывать данные из входящих писем; приложение, отображающее ленту Twitter, может обрабатывать данные, содержащиеся в твитах третьих лиц; а новостной агрегатор будет включать данные, поступающие с других веб-сайтов.

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

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

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

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

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

Более практичная стратегия — поочерёдно проходить по точкам ввода данных, внося уникальное значение в каждую, и затем отслеживать ответы приложения. Особое внимание стоит уделять функционалу комментариев к блогам, форумам и другим областям, где предполагается публикация информации между пользователями. Когда отправленное значение появляется в ответе, необходимо убедиться, что данные действительно были сохранены и используются в разных запросах, а не только отражаются немедленно.

После выявления связи между точкой ввода и вывода для каждой такой пары нужно определить контекст появления данных в ответе и протестировать подходящие полезные нагрузки для этого контекста. На этом этапе методика тестирования аналогична поиску reflected xss.

Last updated