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

XSS при слабой CSP (unsafe-inline)

Reflected XSS эксплуатируется благодаря CSP с 'unsafe-inline'. Исправление требует nonce-based CSP.

hardgolangPro
Задача
# XSS при слабой Content-Security-Policy (unsafe-inline) ## Сценарий Вы проводите аудит безопасности интернет-магазина **SecureShop**. Разработчик добавил заголовок `Content-Security-Policy` (CSP) с целью защиты от XSS — и считает задачу закрытой. Однако значение политики содержит `script-src 'unsafe-inline' 'self'`, что прямо разрешает выполнение inline-скриптов и сводит защиту от XSS к нулю. Параллельно в коде каталога есть кастомная функция шаблона, отключающая HTML-экранирование. У приложения есть бот-администратор, который проверяет жалобы через форму **«Report to Admin»** — он откроет любую переданную ссылку. ## Цель 1. Изучите CSP-заголовок ответа в Network → Headers и определите его слабость. 2. Найдите Reflected XSS в поиске каталога (`/catalog?q=...`). 3. Убедитесь, что `<script>` исполняется — несмотря на присутствие CSP-заголовка. 4. Сформируйте вредоносную ссылку, отправляющую `document.cookie` на ваш Exploit Server. 5. Через `/report` доставьте ссылку администратору, перехватите его сессию и заберите флаг с `/admin`. ## Теория **Content-Security-Policy** — заголовок, ограничивающий, какие источники скриптов и стилей браузер имеет право исполнять. Грамотная CSP — мощный второй слой защиты от XSS: даже если в страницу проник `<script>`, браузер его не запустит. Но защита работает только при правильной политике. Директива `'unsafe-inline'` в `script-src` явно разрешает любые inline-скрипты, что **полностью отключает** CSP как XSS-mitigation. Современный безопасный подход — nonce-based CSP: на каждый запрос сервер генерирует уникальный токен (nonce) и помечает им только свои легитимные `<script nonce="...">`. Inline-скрипты без nonce браузер блокирует. **Уязвимый паттерн (двойная ошибка):** ```go // (1) Шаблонизатор отключает экранирование пользовательского ввода: funcMap := template.FuncMap{ "marker": func(s string) template.HTML { return template.HTML(s) }, } // шаблон: <p>Showing results for "{{marker .Query}}"</p> // (2) CSP с unsafe-inline — никакой защиты второго слоя: w.Header().Set("Content-Security-Policy", "default-src 'self'; script-src 'unsafe-inline' 'self'; style-src 'self' 'unsafe-inline'") ``` ## Точка входа атаки | Параметр | Значение | |----------|----------| | Обычный пользователь | `demo` / `demo` | | Уязвимый эндпоинт | `GET /catalog?q=...` (reflected XSS в поиске) | | Доставка боту | `POST /report` (бот откроет URL) | | Цель | `GET /admin` (требует роль `admin`) | | Exploit Server | внешний URL для приёма украденных данных (см. панель лабы) |
🚧 Сайт в разработке. Полный функционал пока недоступен. Все вопросы — support@hackandfix.ru