Stored XSS в комментариях к товару
Комментарии к товарам выводятся без экранирования — Stored XSS позволяет украсть cookie администратора.
mediumphpPro
Задача
# Stored XSS: кража сессии админа через комментарии к товару
## Сценарий
Перед вами PHP-приложение интернет-магазина SecureShop. На странице каждого товара есть форма комментариев: любой авторизованный пользователь может оставить отзыв, который сохраняется в базе данных и потом отображается на той же странице товара всем посетителям. То есть значение поля комментария — это **stored**-данные: они переживают одну сессию атакующего и видны другим пользователям при следующих визитах.
При отображении сохранённых комментариев приложение вставляет их текст в HTML-страницу **без экранирования специальных символов HTML**. Это превращает форму комментария в полноценный канал Stored XSS: введённая один раз HTML-разметка (включая исполняемые теги вида `<script>`, `<img onerror=..>`, `<svg onload=..>`) сохраняется в БД и далее автоматически исполняется в браузере **каждого** пользователя, открывающего страницу этого товара.
В отличие от Reflected XSS, payload не нужно доставлять жертве через специально сконструированную ссылку — он уже хранится на сервере и срабатывает при обычном визите. Это делает Stored XSS значительно опаснее: даже технически грамотный пользователь, который никогда не открывает подозрительные URL, всё равно становится жертвой при заходе на легитимную страницу товара.
## Цепочка атаки
В приложении есть отдельная служебная форма «Report to Admin», через которую обычный пользователь может пожаловаться администратору и приложить ссылку. Бот-администратор открывает присланную ссылку в собственном авторизованном браузере (с активной admin-сессией). Соединив stored-XSS на странице товара с этой формой, обычный пользователь получает прямой канал доставки JavaScript в браузер админа:
1. Оставить вредоносный комментарий на товаре (payload крадёт `document.cookie`).
2. Отправить ссылку на страницу этого товара через Report-форму.
3. Бот-админ открывает ссылку → payload исполняется в его браузере → `session_token` уходит на Exploit Server атакующего.
4. Атакующий устанавливает украденный cookie у себя в браузере и заходит в админский раздел.
5. На странице `/admin` приложение отдаёт CTF-флаг.
## Контекст уязвимости
Stored XSS в системах комментариев — один из наиболее распространённых классов веб-уязвимостей (CWE-79). Исторические примеры: червь Samy на MySpace (2005, около миллиона заражённых профилей за 20 часов), уязвимости в WordPress Comments (CVE-2019-9787 и аналогичные), баги в системах review-комментариев крупных маркетплейсов.
Корневая причина одна и та же: пользовательский контент попадает в HTML-страницу без преобразования спецсимволов в HTML-сущности. Браузер не различает «текст от разработчика» и «текст от пользователя» — он рендерит то, что приходит в HTML-ответе, как код.
## Цели
1. Найдите форму комментариев и подтвердите, что HTML-разметка из текста комментария **исполняется** при отображении страницы (а не выводится как текст).
2. Сконструируйте комментарий, исполнение которого в браузере жертвы доставит её сессионный идентификатор на ваш Exploit Server.
3. Доставьте администратора на страницу с таким комментарием через форму отчёта; перехватите его сессию; войдите от его имени на админский раздел и заберите CTF-флаг.
## Данные
| Параметр | Значение |
|----------|----------|
| Обычный пользователь | `demo` / `demo` |
| Exploit Server | ссылка «Exploit Server» на панели лабы |
| Форма комментария | страница товара в каталоге |
| Форма доставки боту | `/report` |
| Цель | админский раздел приложения |