DOM XSS через location.hash и innerHTML
Клиентский JavaScript читает location.hash и вставляет через innerHTML без санитизации. Выполни произвольный JS и укради cookie администратора.
easypythonPro
Задача
# DOM-based XSS через URL-фрагмент
## Сценарий
Перед вами Flask-приложение интернет-магазина SecureShop. На странице каталога подключён небольшой клиентский JavaScript-скрипт, который читает «фрагмент» URL-адреса (часть после `#`), декодирует его и отображает наверху списка товаров как метку «Filtering by:..» — типичная UX-фича для запоминаемых ссылок-фильтров.
В отличие от server-side XSS (Reflected/Stored), у этого варианта своя специфика: **фрагмент URL не отправляется на сервер вообще** — браузер хранит его локально и обрабатывает только клиентский код. То есть никакая серверная санитизация, никакой `|safe` в шаблоне, никакой WAF не имеют отношения к проблеме. Уязвимость и её фикс полностью живут в JavaScript-коде в браузере.
В реализации этого скрипта декодированный фрагмент склеивается со статической HTML-обёрткой и присваивается элементу через свойство, которое **парсит строку как HTML** и вставляет результат в DOM. Любые HTML-теги в фрагменте URL — включая теги-векторы исполнения JavaScript — оказываются настоящими тегами в дереве страницы и срабатывают с правами скрипта на этой странице, в том числе видят сессионные cookies пользователя.
В сочетании с формой «Report to Admin» (бот открывает присланный URL и взаимодействует со страницей в собственной авторизованной сессии) это даёт классический канал кражи административной сессии и эскалации до админских прав, под которыми приложение отдаёт CTF-флаг.
## Цели
1. Изучите клиентский JavaScript на странице каталога (DevTools → Sources). Подтвердите, что фрагмент URL декодируется и попадает в DOM **через свойство, которое парсит HTML**, а не через свойство, устанавливающее текстовое содержимое.
2. Сконструируйте URL c фрагментом, который при открытии страницы в браузере жертвы извлечёт `document.cookie` и доставит его на ваш Exploit Server.
3. Доставьте этот URL администратору через форму отчёта; перехватите его сессию; войдите от его имени в админский раздел и заберите CTF-флаг.
## Данные
| Параметр | Значение |
|----------|----------|
| Обычный пользователь | `demo` / `demo` |
| Exploit Server | ссылка «Exploit Server» на панели лабы |