Weakness reference
CWE-1336

Improper Neutralization of Special Elements Used in a Template Engine

Server-side template injection SSTI occurs when user input is embedded directly into a template engine without proper escaping or sanitization. An attacker can…

01Summary

Server-side template injection (SSTI) occurs when user input is embedded directly into a template engine without proper escaping or sanitization. An attacker can inject template syntax—such as variable references, loops, or function calls—that the template engine interprets and executes on the server, potentially leading to arbitrary code execution. This weakness is particularly dangerous because template engines are designed to be powerful and flexible, making it easy for injected code to access sensitive data or system resources.

02How It Happens

Template engines (Jinja2, Twig, ERB, Handlebars, etc.) are designed to process directives and expressions embedded in template files. When a web application accepts user input and inserts it directly into a template without escaping, the template engine treats that input as part of its syntax rather than as plain text. An attacker can craft input containing template directives—such as variable lookups, filters, or function calls—that execute during template rendering. The vulnerability is compounded when the template engine has access to dangerous objects or methods (like file I/O, system commands, or reflection APIs), which the injected code can invoke.

03Real-World Impact

Successful SSTI attacks can lead to complete server compromise. An attacker may read sensitive files, access environment variables containing database credentials or API keys, execute system commands, or instantiate arbitrary objects to trigger further code execution. In multi-tenant environments, SSTI can allow one user to access another user's data. Even in restricted template sandboxes, creative attackers have found ways to break out and reach dangerous functionality. The impact ranges from information disclosure to remote code execution, depending on the template engine and the application's security posture.

04Vulnerable & Fixed Patterns

Vulnerable pattern
from jinja2 import Template

user_input = request.args.get('name', '')
template_string = f"Hello, {user_input}!"
template = Template(template_string)
output = template.render()
return output

Why it's vulnerable:
The user input is directly interpolated into the template string before it is parsed. An attacker can inject template syntax (e.g., {{ 7 * 7 }} or {{ config }}) that the Jinja2 engine will evaluate.

Fixed pattern
from jinja2 import Template

user_input = request.args.get('name', '')
template_string = "Hello, {{ name }}!"
template = Template(template_string)
output = template.render(name=user_input)
return output
Vulnerable pattern
<?php
$user_input = $_GET['name'] ?? '';
$template = "Hello, {$user_input}!";
echo eval('?>' . $template);
?>

Why it's vulnerable:
User input is embedded directly into a string that is then evaluated as PHP code. An attacker can inject PHP syntax or template directives that execute on the server.

Fixed pattern
<?php
$user_input = $_GET['name'] ?? '';
$template = "Hello, " . htmlspecialchars($user_input, ENT_QUOTES, 'UTF-8') . "!";
echo $template;
?>

05Prevention Checklist

Never concatenate user input into template strings.
Always pass user data as variables or context parameters to the template engine, keeping it separate from template syntax.
Use template auto-escaping.
Enable auto-escaping in your template engine (e.g., autoescape=True in Jinja2) so that user-supplied values are HTML-encoded by default.
Avoid dynamic template compilation.
Do not construct template source code from user input; load templates from trusted files only.
Restrict template engine capabilities.
If using a template engine, disable or sandbox dangerous functions (file I/O, system calls, reflection) if the engine supports it.
Validate and allowlist input.
Where feasible, restrict user input to a known safe set of values (e.g., a dropdown list) rather than free-form text.
Use a security-focused template engine.
Some engines (like Handlebars with strict mode) offer safer defaults; prefer them over engines with permissive evaluation.

06Signs You May Already Be Affected

Look for unexpected template syntax or expressions in your application logs, error messages, or user-submitted content that appears to have been evaluated rather than displayed as plain text. Check for unusual file access patterns or system command execution in server logs around the time user input is processed. If you see error messages revealing internal object structures, configuration details, or file paths in response to specially crafted input, SSTI may be present.

07Related Recent Vulnerabilities