Get a free application, infrastructure and malware scan report - Scan Your Website Now

Server-Side Template Injection(SSTI)

Server-Side Template Injection (SSTI) occurs when unvalidated user input is processed by a server-side template engine, leading to potential security risks. This allows attackers to inject malicious payloads into the template, which the server processes and executes.

Depending on the template engine and its capabilities, SSTI can lead to severe consequences, including data exfiltration, privilege escalation, or complete server compromise.

What are Template Engines?

Template engines are widely used in modern web development to dynamically render content by combining static templates with dynamic data. This enables them to separate business logic with presentation logic.

 

template-engine

 

template-engine-example

When web pages come from a web template, they can structure the component of web pages in such a way that can be modified independently of each other. A component can include anything like header, footer, content such as videos, images, audio. Templates Engines are commonly used to:

  • Displays information about users, products, and companies
  • Displays gallery of photos, and  videos
  • Sell products online
  • Sends bulk emails

Examples include Jinja2 (Python), Freemarker (Java), Twig (PHP), and Velocity (Java).

How Does SSTI Work?

The exploitation of SSTI typically involves the following steps:

Identifying Vulnerable Input Points: The attacker looks for input fields or parameters that are used in server-side template rendering.

Crafting Malicious Payloads: Malicious code is crafted to exploit the template engine’s features. For instance, attackers may inject expressions or functions specific to the template engine.

Evaluating the Payload: When the template engine processes the malicious payload, it executes unintended code or accesses unauthorized resources.

Achieving Exploitation Goals: The attacker leverages the vulnerability for activities such as code execution, data theft, or lateral movement within the application.

Examples of Server-Side Template Injection

Let’s look at some examples of SSTI across popular template engines:

  1. Jinja2 (Python):

from flask import Flask, request, render_template_string

@app.route("/")
def index():
user_input = request.args.get("name")
template = f"Hello {{ {user_input} }}"
return render_template_string(template)

An attacker might provide a payload such as:

name={{config.__class__.__init__.__globals__['os'].popen('ls').read()}},/code>

This payload leverages Python’s object attributes to execute system commands.

  1. Twig (PHP):

$loader = new  Twig\Loader\ArrayLoader([
'index' => $template,
]);
$twig = new  Twig\Environment($loader);
echo $twig->render('index', $data);

Payload:

{{ system('id') }}

  1. Freemarker (Java):

Template template = cfg.getTemplate("example.ftl");
Map<String, Object> input = new HashMap<>();
input.put("user", userInput);
template.process(input, writer);

Payload:

${"freemarker.template.utility.Execute"?new()("id")}

Risks Associated with SSTI

SSTI vulnerabilities can have devastating impacts on applications and organizations. Some key risks include:

Remote Code Execution (RCE): Attackers can execute arbitrary code on the server, gaining full control over the system.

Data Theft: Sensitive data, including credentials, API keys, and database records, can be exfiltrated.

Server Takeover: Full server control might be obtained, allowing attackers to escalate privileges and spread laterally(east-west compromise).

Denial of Service (DoS): Malicious payloads can overwhelm the template engine, rendering the application inoperable.

How to Prevent Server Side Template Injection?

Perform Regular Security Testing

To identify SSTI vulnerabilities, use the following methods:

Automated Scanners

DAST Scanners can identify potential SSTI points. These tools scan applications for common SSTI patterns and vulnerabilities, analyzing input fields and templates for improper handling of user-supplied data.

Fuzz Testing

Fuzz testing helps uncover vulnerabilities that automated tools might miss, especially when dealing with less common or custom template engines.

Inject payloads such as {{7*7}} or ${7*7} into potential entry points to test whether the template engine processes the input dynamically. If the response contains the evaluated result (e.g., 49), this indicates the presence of an SSTI vulnerability.

Manual Code Review

Analyze the source code to spot improper template rendering practices.

Follow Input Validation and Whitelisting

URL Whitelisting

Allow only trusted domains or IP ranges. Example:

ALLOWED_DOMAINS = ["https://trusted.com"]
if not url.startswith(tuple(ALLOWED_DOMAINS)):
raise ValueError("Invalid URL")

Reject Private IP Ranges

Block requests to internal or private IP ranges (e.g., 10.x.x.x, 192.168.x.x, 127.0.0.1).

Restrict Network Access

Egress Filtering

Configure firewalls to block unnecessary outbound requests. Allow requests only to approved destinations.

DNS Restrictions

Block DNS rebinding attacks by resolving domain names against an allowlist.

Avoid Direct URL Fetching

Instead of letting users provide raw URLs, use indirect references (e.g., ID mappings):

# Example of indirect URL mapping

URL_MAP = {
"image1": "https://trusted.com/image1.jpg",
"image2": "https://trusted.com/image2.jpg",
}

Sanitize User Inputs

Use libraries or frameworks to validate inputs (e.g., OWASP Validator in Java).

Block special characters often used in SSRF payloads, such as @, ?, #, and IP addresses.

Avoid Dynamic Template Rendering

Refrain from dynamically loading templates based on user input. Always use predefined and static template paths.

For example:

Insecure

template.render(user_input)

Secure

predefined_templates = {"home": "home.html", "profile": "profile.html"}
if user_input in predefined_templates:
template = predefined_templates[user_input]
render_template(template)

Secure Template Engine Usage

Use engines with built-in security features, such as sandboxing or automatic output escaping (e.g., Jinja2 with strict mode). Disable or limit advanced features like code execution or unrestricted variable access.

Enable Content Security Policies (CSP)

Implement a Content Security Policy to prevent execution of malicious scripts or injected code, even if an SSTI vulnerability exists.

Deploy WAF (Web Application Firewall)

WAFs are designed to detect unusual or potentially dangerous behavior in HTTP requests, such as large payloads, special characters, or attempts to dynamically manipulate templates.

For example, the AppTrana WAF uses predefined rule sets and signatures to identify malicious input patterns, including template syntax like {{…}}, ${…}, or <%…%>—all commonly associated with SSTI attacks.

Indusface
Indusface

Indusface is a leading application security SaaS company that secures critical Web, Mobile, and API applications of 5000+ global customers using its award-winning fully managed platform that integrates web application scanner, web application firewall, DDoS & BOT Mitigation, CDN, and threat intelligence engine.

Join 51000+ Security Leaders

Get weekly tips on blocking ransomware, DDoS and bot attacks and Zero-day threats.

We're committed to your privacy. indusface uses the information you provide to us to contact you about our relevant content, products, and services. You may unsubscribe from these communications at any time. For more information, check out our Privacy Policy.

AppTrana

Fully Managed SaaS-Based Web Application Security Solution

Get free access to Integrated Application Scanner, Web Application Firewall, DDoS & Bot Mitigation, and CDN for 14 days

Get Started for Free Request a Demo

Gartner

Indusface is the only cloud WAAP (WAF) vendor with 100% customer recommendation for 4 consecutive years.

A Customers’ Choice for 2024, 2023 and 2022 - Gartner® Peer Insights™

The reviews and ratings are in!