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

DOM XSS через URL-фрагмент (location.hash)

JavaScript на странице каталога читает location.hash и вставляет его в DOM через innerHTML. Укради сессию администратора.

mediumgolangPro
Задача
# DOM XSS через URL-фрагмент (Кража сессии админа) ## Сценарий Вы исследуете интернет-магазин **SecureShop**. На странице каталога работает «подсветка поиска»: при переходе по URL с фрагментом (`#текст`) внутри страницы появляется надпись `Showing results for: текст`. Функция реализована на JavaScript и обрабатывает данные из `location.hash` **на стороне клиента** — фрагмент после `#` никогда не отправляется на сервер. А значит серверная санитизация (даже идеальная) бесполезна — атака происходит полностью в браузере жертвы. ## Цель 1. Найдите в клиентском JavaScript на странице каталога уязвимый источник данных и опасный приёмник (sink). 2. Сформируйте XSS-payload, передав его через URL-фрагмент. 3. Сделайте payload, отправляющий `document.cookie` на ваш Exploit Server. 4. Через форму `/report` доставьте ссылку с payload боту-администратору. 5. Перехватите `session_token` администратора и используйте его для доступа к `/admin`. Заберите флаг. ## Теория **DOM-based XSS** отличается от Reflected/Stored XSS тем, что весь жизненный цикл payload'а проходит на клиенте. Источник данных (source) — `location.hash`, `document.URL`, `document.referrer`, `localStorage`. Приёмник (sink) — `innerHTML`, `outerHTML`, `document.write()`, `eval()`. Между source и sink не происходит обращения к серверу, поэтому WAF, серверная санитизация и логи запросов слепы к этой атаке. URL-фрагмент после `#` обладает уникальным свойством: его не видит серверная сторона, и он сохраняется при переходах. Если разработчик подставляет `location.hash` в `innerHTML` без обработки, любой `<img onerror=...>` или `<svg onload=...>` исполнится в момент рендера. **Уязвимый паттерн:** ```javascript // Source: location.hash (после '#') // Sink: innerHTML — парсит строку как HTML var hash = location.hash; if (hash && hash.length > 1) { var decoded = decodeURIComponent(hash.substring(1)); document.getElementById('search-info').innerHTML = 'Showing results for: ' + decoded; } ``` ## Точка входа атаки | Параметр | Значение | |----------|----------| | Обычный пользователь | `demo` / `demo` | | Уязвимая страница | `GET /catalog` (читает `location.hash` на клиенте) | | Доставка боту | `POST /report` (бот откроет переданный URL) | | Цель | `GET /admin` (требует роль `admin`) | | Exploit Server | внешний URL для приёма украденных данных (см. панель лабы) |
🚧 Сайт в разработке. Полный функционал пока недоступен. Все вопросы — support@hackandfix.ru