SSTI: Format String Injection
Форма восстановления пароля использует str.format() с пользовательским шаблоном — атакующий может читать атрибуты объектов через {username.__class__.__init__.__globals__}.
easypythonPro
Задача
# Server-Side Template Injection: format-строка
## Сценарий
Перед вами Flask-приложение интернет-магазина SecureShop. У администратора есть служебный раздел настроек, в котором редактируется шаблон email-сообщения для восстановления пароля. Шаблон хранится в настройках приложения и при каждом запросе на восстановление пароля используется для подстановки имени пользователя и ссылки на сброс — после чего готовое письмо попадает во внутреннюю почту получателя.
Реализация, на первый взгляд, безобидная: «обычная строковая подстановка». Но автор выбрал для подстановки **встроенный механизм Python**, который изначально проектировался не как «строковый шаблон», а как полноценный мини-язык форматирования. В частности, он умеет обращаться к **атрибутам объектов** — а в Python через цепочку обычных атрибутов любого значения можно дотянуться до глобальных переменных модуля, в котором определён вызывающий код, и оттуда — до окружения процесса. То, что с точки зрения автора было «просто подстановкой имени», на деле превращается в полноценную SSTI-уязвимость, ограниченную лишь синтаксисом конкретного языка форматирования.
Канал доставки письма с результатом подстановки — внутренняя почта в этом же приложении: запросив восстановление пароля для какого-нибудь обычного пользователя, можно из-под этого пользователя прочитать «письмо» и увидеть результат рендеринга шаблона.
## Цели
1. Войдите как администратор и найдите служебный раздел, в котором редактируется тело шаблона письма для восстановления пароля. Учётные данные администратора — в данных лабы.
2. Изучите, что **именно** делает встроенный в стандартную библиотеку механизм строковой подстановки Python: какие конструкции он принимает, и какие из них выходят за пределы «вставить значение по имени».
3. Подберите шаблон, который через эти возможности раскроет внутренние данные процесса и в итоге утечёт CTF-флаг. Чтобы увидеть результат, запросите восстановление пароля для обычного пользователя `demo` и зайдите в его внутреннюю почту.
## Данные
| Параметр | Значение |
|----------|----------|
| Обычный пользователь | `demo` / `demo` |
| Администратор | `admin` / `SuperSecret` |