Server-side template injection

What is Server-Side Template Injection?

Server-Side Template Injection (SSTI) occurs when an attacker is able to inject malicious payloads into a server-side template. These payloads are then executed on the server due to improper handling of user input.

How Does It Happen?

  • SSTI arises when user input is directly concatenated into a template rather than being passed as sanitized data.

  • Example of safe code (user input is treated as data)

$output = $twig->render("Dear {first_name}, ", array("first_name" => $user.first_name));

Example of vulnerable code (user input is concatenated):

$output = $twig->render("Dear " . $_GET['name']);

Attack URL:

http://vulnerable-website.com/?name={{bad-stuff-here}}

Impact of SSTI

At the severe end, SSTI can lead to:

  1. Remote Code Execution (RCE): Execute arbitrary commands on the server.

  2. Sensitive Data Exposure: Gain access to environment variables or sensitive files.

  3. Other Attacks: Use SSTI as a basis for XSS, SSRF, or further escalation.


Constructing an SSTI Attack

The process can be divided into four phases:

  1. Detect

  2. Identify

  3. Exploit

  4. Escalate (Read, Explore, Attack)


1. Detect

Detecting SSTI is challenging but critical. Use fuzzing or specific payloads to observe how the input is processed.

How to Detect SSTI

  • Inject special characters used in template syntax (${{<%[%'"}}%).

  • If an exception or error message is triggered, it might indicate SSTI.

Example: Mathematical Operation

  • Inject the payload:

http://vuln-website.com/?username=${7*7}

If the output is:

Hello 49
  • This confirms SSTI as the server interpreted the template syntax.

Code Context Detection

If the server uses template syntax for rendering:

greeting = getQueryParameter('greeting');
engine.render("Hello {{"+greeting+"}}", data)
  1. Test for XSS:

http://vuln-website.com/?greeting=data.username<tag>

Inject template syntax to escape the statement:

http://vuln-website.com/?greeting=data.username}}<tag>
  • If output is: Hello Mary<tag> → SSTI is present.

  • If an error occurs → Possibly no SSTI or a different engine.

2. Identify the Template Engine

Once a potential SSTI is detected, the next step is identifying the template engine.

Techniques for Identification

  1. Invalid Syntax Testing

    • Submit invalid syntax and observe the error message:{{7/0}} Example Error (Ruby-based ERB engine):

(erb):1:in `<main>': undefined local variable or method `foobar' for main:Object (NameError)
  1. Test Engine-Specific Payloads

  • Different template engines interpret payloads differently:

Payload: {{7*'7'}}
Twig Output: 49
Jinja2 Output: 7777777
  1. Common Syntax Examples:

${}
${foobar}
{{7*7}}
{{foobar}}
<%= 7/0 %>

3. Exploit

After identifying SSTI, the next step is exploitation. The level of exploitation depends on the template engine and server context.

Read

  1. Study Documentation:

    • Understand the template engine’s syntax and features.

    • Example for Python-based Mako template engine

<%
import os
x = os.popen('id').read()
%>
${x}
  1. Read About Security Implications:

    • Identify known vulnerabilities and exploit techniques.

Explore

  • Many template engines expose powerful objects such as self or environment.

  • Example in Java:

${T(java.lang.System).getenv()}

Attack

  • Escalate from SSTI to RCE or sensitive data access.

  • Example RCE:

{{config.__class__.from_envvar("PATH")}}

Steps to Test for SSTI

  1. Inject payloads containing special characters:

    • Examples: ${{<%[%'"}}%

  2. Look for exceptions or anomalies in the server response.

  3. Test template syntax-specific payloads to confirm exploitation potential.


Advanced SSTI Techniques

1. SSTI in Plaintext Context

  • Output rendered as text (e.g., Hello Mary).

  • Often mistaken for XSS vulnerabilities.

2. SSTI in Code Context

  • Exploit by escaping template syntax and injecting malicious code.

3. Error-Based SSTI

  • Trigger parsing errors to reveal template engine details or sensitive data.


Mitigations for SSTI

  1. Avoid Direct Concatenation:

    • Always pass user input as data, not as part of the template string.

  2. Use Secure Template Engines:

    • Use engines with built-in sanitization or restrict access to dangerous objects.

  3. Validate and Sanitize User Input:

    • Ensure that user input cannot contain template syntax.

  4. Restrict Template Functionality:

    • Limit access to objects, functions, or system calls in the template engine.

  5. Error Handling:

    • Do not expose detailed error messages that could reveal sensitive information.

Last updated

Was this helpful?