Перейти к содержимому
← Каталог php XSS

DOM XSS через URL-фрагмент

JavaScript читает location.hash и вставляет значение через innerHTML — DOM XSS без участия сервера.

mediumphpPro
Задача
# DOM-based XSS через URL-фрагмент ## Сценарий Перед вами PHP-приложение интернет-магазина SecureShop. На странице каталога подключён небольшой клиентский JavaScript-скрипт, который читает «фрагмент» URL-адреса (часть после `#`), декодирует его и отображает над списком товаров как метку «Filtering by tag:..» — типичная UX-фича для запоминаемых ссылок-фильтров. В отличие от server-side XSS (Reflected/Stored), у этого варианта своя специфика: **фрагмент URL не отправляется на сервер вообще** — браузер хранит его локально и обрабатывает только клиентский код. То есть никакая серверная санитизация (`htmlspecialchars()`, фильтры в Twig, экранирование в шаблонах PHP), никакой WAF не имеют отношения к проблеме. Уязвимость и её фикс полностью живут в JavaScript-коде в браузере. В реализации этого скрипта декодированный фрагмент склеивается со статическим префиксом и присваивается элементу через свойство, которое **парсит строку как HTML** и вставляет результат в DOM. Любые HTML-теги в фрагменте URL — включая теги-векторы исполнения JavaScript — оказываются настоящими тегами в дереве страницы и срабатывают с правами скрипта на этой странице, в том числе видят сессионные cookies пользователя. В сочетании с формой «Report to Admin» (бот открывает присланный URL и взаимодействует со страницей в собственной авторизованной сессии) это даёт классический канал кражи административной сессии и эскалации до админских прав, под которыми приложение отдаёт CTF-флаг. ## Ключевые наблюдения - **Sink:** строка с JavaScript присваиванием значения в свойство, которое парсит HTML. Это видно прямо в HTML-ответе страницы каталога (View Source). - **Source:** `location.hash` после `decodeURIComponent`. Никакой санитизации между source и sink нет. - **Доставка:** форма `/report` принимает произвольный URL и передаёт его боту-администратору. Бот авторизован и открывает ссылку в своём браузере; фрагмент обрабатывается локально. - **Ограничение `innerHTML`:** тег `<script>` через `innerHTML` не исполняется (HTML5-спецификация). Используются другие теги с авто-обработчиками событий (`<img>`, `<svg>`, `<details>`, `<iframe>` через `javascript:` URL и т.п.). ## Цели 1. Изучите клиентский JavaScript на странице каталога (DevTools → Sources, или Ctrl+U). Подтвердите, что фрагмент URL декодируется и попадает в DOM **через свойство, которое парсит HTML**, а не через свойство, устанавливающее текстовое содержимое. 2. Сконструируйте URL c фрагментом, который при открытии страницы в браузере жертвы извлечёт `document.cookie` и доставит его на ваш Exploit Server. 3. Доставьте этот URL администратору через форму отчёта; перехватите его сессию; войдите от его имени в админский раздел и заберите CTF-флаг. ## Данные | Параметр | Значение | |----------|----------| | Обычный пользователь | `demo` / `demo` | | Целевая страница | `/catalog` | | Канал доставки админу | форма `/report` | | Exploit Server | ссылка «Exploit Server» на панели лабы |
🚧 Сайт в разработке. Полный функционал пока недоступен. Все вопросы — support@hackandfix.ru