Server-Side Template Injection (SSTI)
SSTI occurs when user input is embedded into a template engine without sanitization, allowing attackers to execute arbitrary code on the server.
What Is SSTI?
Server-Side Template Injection occurs when user-controlled data is passed directly into a template engine's rendering function. Template engines (Jinja2, Twig, Freemarker, Pebble) execute expressions inside their syntax — if an attacker's input reaches the template, they can run arbitrary code.
SSTI is functionally equivalent to Remote Code Execution.
How It Works
Jinja2 (Python/Flask):
# Vulnerable — user input rendered as a template
from flask import Flask, request, render_template_string
@app.route("/greet")
def greet():
name = request.args.get("name", "")
return render_template_string(f"Hello {name}!") # name goes INTO the templateAn attacker submits:
name={{7*7}}
Response: Hello 49! — the template evaluated the expression.
Escalating to RCE:
name={{config.__class__.__init__.__globals__['os'].popen('id').read()}}
Response: Hello uid=1000(www-data)... — full command execution.
Real-World Impact
- Remote Code Execution — execute arbitrary OS commands
- Full server compromise — read files, install backdoors, pivot internally
- Secret theft — read environment variables including database credentials and API keys
- Denial of Service — crash the application with infinite loops or memory exhaustion
How to Fix
Never pass user input into render_template_string:
# Safe — template is static, only values change
from flask import render_template
@app.route("/greet")
def greet():
name = request.args.get("name", "")
return render_template("greet.html", name=name)greet.html:
<!-- Jinja2 auto-escapes {{ name }} in HTML templates -->
<p>Hello {{ name }}!</p>If dynamic templates are required — use a sandboxed environment:
from jinja2.sandbox import SandboxedEnvironment
env = SandboxedEnvironment()
template = env.from_string(user_template)
result = template.render(name=safe_value)Note: Jinja2's sandbox has been bypassed before — avoid dynamic templates from untrusted input entirely when possible.
What VibeWShield Detects
VibeWShield injects template-syntax probes ({{7*7}}, ${7*7}, <%= 7*7 %>) into parameters and checks whether responses contain 49 or other evaluated expressions. It covers Jinja2, Twig, Freemarker, Velocity, and ERB template engines.
Free security scan
Test your app for Server-Side Template Injection (SSTI)
VibeWShield automatically checks for Server-Side Template Injection (SSTI) and 40+ other vulnerabilities using 63 scanners — in under 3 minutes, no signup required.
Scan your app free