(Stored XSS) Хранимый межсайтовый скриптинг
В этом разделе мы объясним, что такое сохранённый межсайтовый скриптинг (XSS), опишем последствия атак сохранённого XSS и расскажем, как находить уязвимости сохранённого 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, включая кражу данных, выполнение действий от имени пользователя и так далее.
С точки зрения эксплуатации, ключевое отличие между отражённым и сохранённым XSS заключается в том, что сохранённая уязвимость позволяет осуществлять полностью самодостаточные атаки непосредственно через приложение. Атакующему не нужно находить внешний механизм, чтобы заставить других пользователей отправлять особый запрос с его эксплойтом. Вместо этого он помещает вредоносный код в само приложение и просто ждёт, пока пользователи его встретят.
Это особенно важно в случаях, когда уязвимость проявляется только для пользователей, которые уже вошли в приложение. Если XSS отражённый, жертва должна быть аутентифицирована как раз в момент запроса, иначе атака не сработает. Если же XSS сохранённый — пользователь гарантированно будет залогинен, когда столкнётся с эксплойтом.
Хранимый XSS в различных контекстах
Существуют различные типы сохранённого межсайтового скриптинга. Местоположение данных в ответе приложения определяет тип полезной нагрузки для эксплуатации уязвимости и может влиять на последствия.
Также, если приложение каким-либо образом валидирует или обрабатывает данные перед их сохранением или отображением, это тоже оказывает влияние на необходимый вид XSS-пейлоада.
Как находить и тестировать уязвимости сохранённого XSS
Многие уязвимости сохранённого XSS можно найти с помощью сканера уязвимостей Burp Suite.
Ручное тестирование сохранённого XSS может быть затруднительным. Необходимо проверить все релевантные «входные точки», через которые данные, контролируемые атакующим, могут попасть в приложение, и все «выходные точки», где эти данные могут быть впоследствии выведены в ответах приложения.
Entry points into the application's processing include:
Параметры или другие данные внутри строки запроса URL и тела запроса.
Путь файла в URL.
HTTP-заголовки (для которых отражённый XSS обычно невозможно эксплуатировать).
Любые каналы (out-of-band routes), по которым злоумышленник может доставить данные в приложение. Конкретные каналы зависят исключительно от реализованного функционала приложения: например, веб-почтовое приложение будет обрабатывать данные из входящих писем; приложение, отображающее ленту Twitter, может обрабатывать данные, содержащиеся в твитах третьих лиц; а новостной агрегатор будет включать данные, поступающие с других веб-сайтов.
Выходные точки — это любые HTTP-ответы, возвращаемые любому виду пользователя приложения в любой ситуации.
Первый шаг при тестировании — определить, где значения, отправленные во входные точки, попадают в выходные точки приложения. Это может быть сложно, потому что:
Данные, отправляемые через любую входную точку, теоретически могут всплыть в любой выходной точке. Например, пользовательское отображаемое имя может появиться в каком-то скрытом административном логе.
Данные, которые в настоящее время хранятся приложением, часто могут быть перезаписаны другими действиями (например, список последних поисков быстро переполняется по мере использования приложения).
Тщательное выявление связей между всеми входными и выходными точками подразумевает поочерёдное тестирование каждой пары: отправить конкретное значение через входную точку, перейти к определённой выходной точке и проверить, появилось ли значение. В реальности у сложных приложений такой подход малореалистичен.
Более практичная стратегия — поочерёдно проходить по точкам ввода данных, внося уникальное значение в каждую, и затем отслеживать ответы приложения. Особое внимание стоит уделять функционалу комментариев к блогам, форумам и другим областям, где предполагается публикация информации между пользователями. Когда отправленное значение появляется в ответе, необходимо убедиться, что данные действительно были сохранены и используются в разных запросах, а не только отражаются немедленно.
После выявления связи между точкой ввода и вывода для каждой такой пары нужно определить контекст появления данных в ответе и протестировать подходящие XSS-пейлоады для этого контекста. На этом этапе методика тестирования аналогична поиску reflected xss.
Last updated