FlawOpen

flawopen.com/SSTI/Объяснение

Что такое серверная инъекция в шаблон?

CWE-1336: Server-Side Template InjectionСправочная страница
Краткий ответ

Серверная инъекция в шаблон возникает, когда недоверенный ввод интерпретируется как исходный код шаблона, а не передаётся как данные. Последствия зависят от движка, конфигурации и доступных возможностей: от вычисления выражений до выполнения кода на сервере. Не всякая SSTI приводит к выполнению кода.

УЯЗВИМО — ввод формирует шаблон
# Python / Jinja2
template = f"Hello {name}!"
return render_template_string(template)

# Input: {{ 7*7 }} renders as "49"
# This confirms expression evaluation;
# impact still depends on engine access.

// Java / Freemarker
String tpl = "Welcome " + userName;
new Template("t", tpl, cfg)
    .process(model, out);
ИСПРАВЛЕНО — ввод является данными
# The template is a fixed string the
# developer wrote. The user value is
# passed in as a variable.
return render_template(
    "greeting.html", name=name
)

# Or with a literal template string:
return render_template_string(
    "Hello {{ name }}!", name=name
)

// Java equivalent: template from file,
// user value in the model map.

Ключевое различие

У любого шаблонизатора два вида входных данных: сам шаблон и данные контекста. Шаблон — это программа, а данные — значения, которые она читает. SSTI возникает, когда пользовательскому вводу позволяют перейти из категории данных в исходный код шаблона.

Это та же структурная ошибка, что и SQL-инъекция, при которой данные объединяют с текстом запроса, и Log4Shell, где данные попадали в вычислитель выражений через сообщение журнала. Исправление основано на одном принципе: программа остаётся неизменной, а недоверенные значения передаются отдельным каналом параметров.

Когда последствия могут включать выполнение кода

Если движок предоставляет шаблону мощные объекты или методы, атакующий может получить доступ к чувствительным возможностям приложения. Возможность выполнения кода зависит от движка, версии, конфигурации, песочницы и модели данных. Другие последствия — раскрытие данных и исчерпание ресурсов. Считайте управляемый пользователем исходный код шаблона активной логикой; не полагайтесь только на песочницу без ограничения доступных объектов и ресурсов рендеринга.

Как обнаружить

{{7*7}} ${7*7} <%= 7*7 %> #{7*7}

Если ответ содержит 49 вместо исходного текста, ввод вычисляется как синтаксис шаблона. Такие короткие арифметические проверки помогают выявить вычисление в разрешённой тестовой среде; синтаксис различается, поэтому сам по себе не позволяет надёжно определить движок.

Часто задаваемые вопросы

Это то же самое, что XSS?

Нет. Клиентская инъекция в шаблон выполняется в браузере жертвы и может быть разновидностью XSS. SSTI вычисляется на сервере внутри процесса приложения. Последствия зависят от движка и доступных возможностей; некоторые конфигурации допускают выполнение кода на сервере, но это не происходит автоматически при любой SSTI.

Автоэкранирование предотвращает SSTI?

Нет. Автоэкранирование обрабатывает выводимые значения, но не мешает разобрать значение как синтаксис шаблона. Оно помогает против XSS в выводе, но не против внедрения в исходный текст шаблона.

Безопасно ли разрешить администраторам редактировать шаблоны?

Считайте переданный пользователем исходный код шаблона исполняемой логикой и по умолчанию не обрабатывайте его в основном контексте приложения. Если такая функция необходима, используйте движок для ограниченных шаблонов, предоставляйте минимум инертных данных и ограничивайте CPU, память, размер вывода и время. Песочница снижает доступ, но сама по себе не является полной границей безопасности.

Источники

См. также SSTI: причина, последствия и защита от инъекции в шаблон SSTI в FreeMarker и Velocity: безопасные шаблоны Безопасна ли функция Jinja2 render_template_string()?