XSS через атрибут (javascript: URL)
XSS через javascript: URL-схему в атрибуте href. Jinja2 экранирует HTML-сущности, но не блокирует опасные URL-схемы.
mediumpythonPro
Задача
# XSS в атрибуте: опасная URL-схема
## Сценарий
Перед вами Flask-приложение интернет-магазина SecureShop. У каждого пользователя в профиле есть поле «Website» — место для ссылки на личный сайт. На публичной странице профиля приложение рендерит эту ссылку в виде кликабельного `<a>`-элемента: значение из поля Website попадает в атрибут `href`, текст ссылки — в содержимое.
В шаблонизаторе Flask (Jinja2) auto-escape по умолчанию включён, и от классической XSS «вставить тег внутрь HTML-разметки» это защищает: спецсимволы `<`, `>`, `"`, `&` экранируются. Но **HTML-контекст значения** имеет значение: значение, попадающее в **атрибут URL** (`href`, `src`), интерпретируется браузером не как текст, а как URL — и в URL есть свой набор «опасных» конструкций, которые HTML-экранирование не нейтрализует. В частности, существуют URL-схемы, при клике на которые браузер исполняет JavaScript-код прямо из значения URL, без перехода на какой-либо ресурс. Если приложение принимает значение поля «Website» как есть и кладёт его в `href`, обычный пользователь может сохранить в свой публичный профиль такой URL, и любой посетитель его профиля, кликнувший по ссылке, выполнит JavaScript в собственном браузере.
В сочетании с формой «Report to Admin» (бот-администратор открывает присланную ссылку и взаимодействует со страницей в авторизованной сессии) это даёт классический канал кражи административной сессии и эскалации до админских прав, под которыми приложение и отдаёт CTF-флаг.
## Цели
1. Найдите поле в профиле, значение которого выводится в `href` атрибуте ссылки на публичной странице профиля. Подтвердите, что HTML-сущности из этого значения экранируются, но **выбор URL-схемы** значения никак не валидируется.
2. Подберите URL-схему, при которой клик по ссылке вызовет исполнение JavaScript в браузере посетителя страницы профиля. Соберите payload, который из браузера жертвы доставит её сессионный идентификатор на ваш Exploit Server.
3. Доставьте администратора на свою публичную страницу профиля через форму отчёта; перехватите его сессию; войдите от его имени в админский раздел и заберите CTF-флаг.
## Данные
| Параметр | Значение |
|----------|----------|
| Обычный пользователь | `demo` / `demo` |
| Целевая учётная запись | `admin` (пароль не известен — его не нужно угадывать) |