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

XSS через атрибут (javascript: URL)

XSS через javascript: URL-схему в атрибуте href. Go html/template экранирует HTML, но пропускает опасные URL-схемы.

mediumgolangPro
Задача
# XSS в контексте HTML-атрибута (javascript: URL в href) ## Сценарий Вы проводите аудит безопасности интернет-магазина **SecureShop**. Разработчик добавил возможность указать «свой сайт» в профиле пользователя — на странице публичного профиля ссылка отображается как кликабельный `<a href="...">`. Команда уверена, что Go-шаблонизатор экранирует всё опасное автоматически. У приложения есть бот-администратор, который просматривает профили пользователей по жалобам, отправленным через форму **«Report to Admin»** — он переходит по любым ссылкам в профиле. ## Цель 1. Найдите способ внедрить исполняемый JavaScript в поле «Website» так, чтобы шаблонизатор Go не заблокировал значение. 2. Сохраните в профиле вредоносную ссылку, которая при клике крадёт cookie на ваш Exploit Server. 3. Через `/report` отправьте администратору URL на свой публичный профиль. 4. Перехватите `session_token` администратора и используйте его для входа на `/admin`. 5. Получите флаг на странице Admin Panel. ## Теория Go `html/template` контекстно-зависимо экранирует переменные. Внутри `href` шаблонизатор по умолчанию **проверяет URL-схему**: ссылки `javascript:`, `vbscript:`, `data:` фильтруются автоматически. Эта защита отключается, если разработчик помечает значение как «уже безопасный URL» — например, через кастомную функцию шаблона, возвращающую соответствующий тип stdlib. После этого браузер видит `<a href="javascript:...">` и при клике выполняет произвольный JavaScript в контексте сайта — со всеми правами, включая чтение `document.cookie`. **Уязвимый паттерн:** ```go // В funcMap регистрируется обёртка, помечающая строку как доверенный URL: funcMap := template.FuncMap{ "marker": func(s string) template.URL { return template.URL(s) }, } // Шаблон выводит сайт пользователя через эту обёртку: // <a href="{{marker .User.Website}}">{{.User.Website}}</a> ``` После такой обёртки Go-шаблонизатор **перестаёт проверять схему URL** в `href`. Любая строка `javascript:fetch(...)` сохранится в БД, попадёт в HTML и выполнится при клике любого посетителя профиля — включая бота-администратора. ## Точка входа атаки | Параметр | Значение | |----------|----------| | Обычный пользователь | `demo` / `demo` | | Обновление сайта | `POST /profile/website` (поле `website`) | | Публичный профиль | `GET /profile/{username}` | | Доставка боту | `POST /report` (бот откроет URL и кликнет по ссылке) | | Цель | `GET /admin` (требует роль `admin`) | | Exploit Server | внешний URL для приёма украденных данных (см. панель лабы) |
🚧 Сайт в разработке. Полный функционал пока недоступен. Все вопросы — support@hackandfix.ru