flawopen.com/Vulnerabilities/Server-Side Template Injection (SSTI)
Server-Side Template Injection (SSTI): causa e correção
Imagine uma empresa que imprime cartas usando o modelo “Olá, {{ name }}”. O processo seguro fornece ao impressor um modelo fixo e o nome do cliente como dado. O processo inseguro insere o texto do cliente nas instruções do modelo antes de imprimi-lo. Se o mecanismo interpretar esse texto como sintaxe de template, ocorre Server-Side Template Injection. O impacto depende do mecanismo, da configuração, dos objetos disponíveis e das permissões do processo; avaliar uma expressão não significa executar comandos do sistema.
Conceitos principais e termos do subsistema
- Mecanismo de template
- Componente de servidor, como Jinja ou Twig, que analisa a sintaxe de templates e gera saída usando um template e dados de contexto.
- Injeção no código-fonte do template
- Falha em que texto externo é incluído no código-fonte antes da análise, fazendo o mecanismo interpretar o texto como sintaxe em vez de dados.
- Dados de contexto
- Valores passados separadamente a um template fixo e confiável. A separação correta impede que um valor como
{{ 7 * 7 }}seja analisado novamente como código-fonte. - CWE-1336
- Neutralização incorreta de elementos especiais usados em um mecanismo de template. Descreve o processamento inseguro de entrada externa como sintaxe de template.
Fluxo de ataque passo a passo
Entrada controlada pelo atacante chega ao template
Um campo, valor de perfil armazenado ou outra string influenciada externamente chega ao código que cria ou compila um template. O defeito está na composição do código-fonte, não na simples renderização de um valor.
A aplicação mistura dados e instruções do template
A aplicação interpola a string não confiável no código-fonte do template (por exemplo, uma f-string enviada a render_template_string) em vez de usar template estático e valor de contexto separado.
O mecanismo analisa o código combinado
O mecanismo interpreta expressões conforme sua linguagem e configuração. Uma expressão aritmética inofensiva pode demonstrar a avaliação; isso, por si só, não comprova acesso a arquivos, segredos ou comandos do sistema.
O impacto depende dos recursos e da implantação
O impacto adicional depende dos objetos e funções acessíveis, sandbox, restrições do mecanismo e privilégios do processo web. RCE é possível em algumas configurações, mas não é consequência automática de todo SSTI.
Mecanismo e causa raiz
SSTI ocorre quando a aplicação permite que texto influenciado externamente passe a fazer parte do programa do template antes da análise. No Flask/Jinja, o padrão vulnerável monta uma nova string-fonte com dados da requisição e a envia a render_template_string(); escape de HTML protege a saída e não transforma código-fonte não confiável em dado. A correção usa um template fixo e passa o valor separadamente como contexto. Se usuários precisarem criar templates, exponha um modelo mínimo de dados e renderize em um worker isolado com limites de recursos; sandbox é defesa em profundidade, não motivo para expor segredos ou objetos poderosos.
# VULNERABLE: request data becomes template source before parsing.
from flask import Flask, request, render_template_string
app = Flask(__name__)
@app.route("/greet")
def greet():
name = request.args.get("name", "Guest")
# A value such as {{ 7 * 7 }} is interpreted by the template engine.
source = f"<h1>Welcome, {name}!</h1>"
return render_template_string(source)
# HARDENED: fixed template source; request data stays a context value.
from flask import Flask, request, render_template
app = Flask(__name__)
@app.route("/greet")
def greet():
name = request.args.get("name", "Guest")
return render_template("greet.html", name=name)
# templates/greet.html is trusted, static source:
# <h1>Welcome, {{ name }}!</h1>
Sequência do ataque e exemplo conceitual
- 1Origem: Um valor influenciado externamente chega a um caminho que constrói templates.
- 2Composição insegura: A aplicação insere o valor no código-fonte em vez de passá-lo como dado de contexto separado.
- 3Interpretação: O mecanismo analisa o código combinado. Em ambiente autorizado de teste, uma expressão aritmética inofensiva pode confirmar a avaliação.
- 4Impacto condicional: O acesso posterior depende do mecanismo, dos objetos expostos, da configuração e das permissões; não conclua RCE apenas pela avaliação da expressão.
Regras de prevenção e proteção de engenharia
- ✓Mantenha o código-fonte fixo: Carregue templates confiáveis de arquivos ou de um loader controlado; passe entrada do usuário somente como valor de contexto. Não concatene dados de requisição no código-fonte.
- ✓Separe SSTI de injeção HTML: Escape de HTML protege contextos da saída; não corrige um fluxo em que entrada não confiável é analisada como código-fonte de template.
- ✓Limite templates escritos por usuários: Se esse recurso for necessário, use o sandbox do mecanismo para esse caso, exponha um modelo mínimo de dados e renderize em worker isolado com limites de recursos. Siga as notas de segurança do mecanismo.
- ✓Limite o impacto: Execute o renderizador como serviço sem privilégios, com acesso mínimo a arquivos, rede e segredos. Isso contém danos, mas não substitui a correção principal.
- ✓Adicione testes de regressão: Passe uma marca inofensiva como
{{ 7 * 7 }}como dado e confirme que continua sendo dado; teste também que o template vem somente do loader confiável.