criticalCode Injection

Server-Side Template Injection (SSTI)

What Is This Vulnerability?

Server-side template injection occurs when user input is embedded directly into a template engine's template string rather than passed as a data parameter. This allows attackers to inject template directives that the engine evaluates on the server, potentially leading to information disclosure, file reads, or full remote code execution.

Why It Happens

Developers sometimes construct template strings dynamically by concatenating user input with template syntax. This happens when generating personalized emails, dynamic pages, or reports where the template itself is built at runtime instead of using the template engine's variable substitution mechanism safely.

Example Code

Vulnerableapp.py
from flask import Flask, request, render_template_string

app = Flask(__name__)

@app.route("/greet")
def greet():
    name = request.args.get("name", "World")
    template = f"<h1>Hello {name}!</h1>"
    return render_template_string(template)
Fixedapp.py
from flask import Flask, request, render_template_string

app = Flask(__name__)

@app.route("/greet")
def greet():
    name = request.args.get("name", "World")
    template = "<h1>Hello {{ name }}!</h1>"
    return render_template_string(template, name=name)

How Hackers Exploit It

An attacker submits template syntax as input, such as {{7*7}} for Jinja2. If the response shows 49 instead of the literal string, the engine is evaluating the expression. From there, the attacker escalates to reading files ({{config.items()}}), accessing environment variables, or achieving remote code execution by traversing Python's class hierarchy to reach os.popen().

How to Fix It

Never insert user input directly into template strings. Always pass user data as context variables using the template engine's built-in parameter mechanism. If you must use dynamic templates, use a sandboxed template environment like Jinja2's SandboxedEnvironment. Restrict access to dangerous attributes and methods in the template context.

Frequently Asked Questions

How do I test for server-side template injection?
Submit mathematical expressions in the template syntax of the engine you suspect, such as {{7*7}} for Jinja2 or ${7*7} for FreeMarker. If the response contains the evaluated result (49), the application is vulnerable to template injection.
Which template engines are most affected by SSTI?
Jinja2 (Python), Twig (PHP), FreeMarker (Java), and EJS (Node.js) are commonly affected. Any template engine that evaluates expressions can be exploited if user input is concatenated into the template string instead of passed as a data variable.
Can SSTI lead to full server compromise?
Yes. In many template engines, attackers can traverse object hierarchies to access system functions. In Jinja2 for example, the attacker can reach Python's os module through the class hierarchy and execute arbitrary shell commands on the server.

Related Security Topics

Check Your Code for This Vulnerability

Run a free scan to check if your site is affected by server-side template injection (ssti).