SSTI Email: Инъекция шаблона в email-сообщение
SSTI-уязвимость: пользовательский ввод передаётся в template.Parse(), позволяя читать серверные данные.
hardgolangPro
Задача
# SSTI: Server-Side Template Injection в кастомизируемом email-шаблоне
## Сценарий
Вы аудируете внутренний сервис **SecureShop**. Среди новых фич — форма «Восстановление пароля» с возможностью указать собственный текст письма: пользователь вводит сообщение, в нём может использовать плейсхолдеры (имя пользователя, ссылка сброса), а сервер подставляет значения и отправляет email. Команда уверена, что эндпоинт безопасен — пользователь работает только со своим сообщением, а данные подставляются с серверной стороны. По данным внутреннего аудита, контекст подстановки содержит конфиденциальную метку — её требуется извлечь, имея только обычную учётную запись.
## Цель
1. Изучите, как сервер обрабатывает поле `message_template` формы восстановления пароля: как обычная строка с заменой плейсхолдеров или как-то иначе.
2. Определите, какие поля присутствуют в контексте подстановки сервера (для разведки структуры — найдите способ вывести весь контекст одной директивой).
3. Извлеките значение конфиденциальной метки из контекста и получите флаг.
## Теория
Server-Side Template Injection (SSTI) часто появляется именно в email/notification-механизмах: разработчик хочет дать пользователю или администратору возможность кастомизировать шаблон письма (плейсхолдеры имени, ссылки, реквизитов), но вместо безопасной строковой замены использует полноценный шаблонизатор (`text/template`, `Jinja2`, `Twig`, `Handlebars`). Любая шаблонная директива в пользовательском вводе становится исполняемым кодом с доступом к контексту рендеринга.
**Уязвимый паттерн:**
```go
// Пользовательский шаблон письма парсится и исполняется на сервере
tmpl, _ := template.New("email").Parse(userMessageTemplate)
tmpl.Execute(&buf, emailData) // emailData содержит чувствительные поля
```
Для атакующего форма «Восстановление пароля» — особенно «вкусная» цель, потому что (а) обычно доступна без авторизации (или с минимальной авторизацией), (б) email-шаблон часто содержит чувствительные значения для подстановки (токены сброса, временные пароли, идентификаторы), (в) preview email возвращается в ответе формы — это даёт мгновенный feedback-канал для blind-вариантов через timing/conditional payload.
## Точка входа атаки
| Параметр | Значение |
|----------|----------|
| Учётные данные | `demo` / `demo` |
| Эндпоинт | `POST /forgot-password` |
| Уязвимый параметр | `message_template` — пользовательский шаблон email |
| Цель | конфиденциальная метка из контекста подстановки |