1
0
mirror of https://github.com/swisskyrepo/PayloadsAllTheThings.git synced 2026-01-19 14:51:33 +01:00
PayloadsAllTheThings/Server Side Template Injection
2026-01-03 22:50:37 +01:00
..
Images SSI: 2026-01-03 05:20:04 +03:00
Intruder SSTI - Pages splitted by technology 2024-10-23 13:59:18 +02:00
ASP.md Markdown Linting - SSI, SSRF, SSTI 2025-03-26 17:49:42 +01:00
Java.md SSI, SSTI: 2026-01-03 22:20:19 +03:00
JavaScript.md SSTI: 2026-01-03 23:19:26 +03:00
PHP.md SSI, SSTI: 2026-01-03 22:20:19 +03:00
Python.md Merge branch 'master' into master 2026-01-03 19:06:57 +03:00
README.md Unordered list style [Expected: dash; Actual: asterisk] 2026-01-03 22:50:37 +01:00
Ruby.md SSI: 2026-01-03 05:20:04 +03:00

Server Side Template Injection

Template injection allows an attacker to include template code into an existing (or not) template. A template engine makes designing HTML pages easier by using static template files which at runtime replaces variables/placeholders with actual values in the HTML pages.

Summary

Tools

  • Hackmanit/TInjA - An efficient SSTI + CSTI scanner which utilizes novel polyglots

    tinja url -u "http://example.com/?name=Kirlia" -H "Authentication: Bearer ey..."
    tinja url -u "http://example.com/" -d "username=Kirlia"  -c "PHPSESSID=ABC123..."
    
  • epinna/tplmap - Server-Side Template Injection and Code Injection Detection and Exploitation Tool

    python2.7 ./tplmap.py -u 'http://www.target.com/page?name=John*' --os-shell
    python2.7 ./tplmap.py -u "http://192.168.56.101:3000/ti?user=*&comment=supercomment&link"
    python2.7 ./tplmap.py -u "http://192.168.56.101:3000/ti?user=InjectHere*&comment=A&link" --level 5 -e jade
    
  • vladko312/SSTImap - Automatic SSTI detection tool with interactive interface based on epinna/tplmap

    python3 ./sstimap.py -u 'https://example.com/page?name=John' -s
    python3 ./sstimap.py -i -u 'https://example.com/page?name=Vulnerable*&message=My_message' -l 5 -e jade
    python3 ./sstimap.py -i -A -m POST -l 5 -H 'Authorization: Basic bG9naW46c2VjcmV0X3Bhc3N3b3Jk'
    

Methodology

Detection and Exploitation Techniques

Original research:

Rendered

Rendered technique workflow

Applicability: detection, exploitation

When the rendered template is displayed to the attacker, Rendered technique can be used to include the results of the injected code on the page.

Error-Based

Error-Based technique workflow

Applicability: detection, exploitation

When the errors are verbosely displayed to the attacker, Error-Based technique can be used to trigger the error message containing the results of the injected code.

Boolean-Based

Boolean-Based technique workflow

Applicability: detection, blind exploitation, blind data exfiltration

Boolean-Based technique can be used to conditionally trigger an error to indicate success or failure of the injected code.

Time-Based

Time-Based technique workflow

Applicability: limited detection, blind exploitation, blind data exfiltration

Time-Based technique can be used to conditionally trigger the delay to indicate success or failure of the injected code.

Triggering the delay often requires guessing payloads for code evaluation or OS command execution.

Out of Bounds

Applicability: limited detection, exploitation

Out of Bounds technique can be used to expose results of the injected code through other channels (e.g. by connecting to an attacker-controlled server).

This technique often requires guessing payloads for code evaluation or OS command execution.

Polyglot-Based

Polyglot-Based technique workflow

Applicability: detection

Polyglot-Based technique can be used to quickly determine the template engine by checking how it transforms different payloads.

Universal Detection Payloads

Polyglot to trigger an error in presence of SSTI vulnerability:

${{<%[%'"}}%\.

Common tags to test for SSTI with code evaluation:

{{ ... }}
${ ... }
#{ ... }
<%= ... %>
{ ... }
{{= ... }}
{= ... }
\n= ... \n
*{ ... }
@{ ... }
@( ... )

Rendered SSTI can be checked by using mathematical expressions inside the tags:

7 * 7

Error-Based SSTI can be checked by using this payload inside the tags:

(1/0).zxy.zxy

If the error caused by that payload is displayed verbosely, it can be checked to guess the language used for code evaluation:

Error Language
ZeroDivisionError Python
java.lang.ArithmeticException Java
ReferenceError NodeJS
TypeError NodeJS
Division by zero PHP
DivisionByZeroError PHP
divided by 0 Ruby
Arithmetic operation failed Freemarker (Java)

To test for blind injections using Boolean-Based technique, the attacker can test pairs of similar payloads wrapped in tags, where one payload evaluates mathematical expression, while the other triggers syntax error:

test ok error
1 (3*4/2) 3*)2(/4
2 ((7*8)/(2*4)) 7)(*)8)(2/(*4

Using at least two pairs of payloads avoids false positives caused by external interference.

Manual Detection and Exploitation

Identify the Vulnerable Input Field

The attacker first locates an input field, URL parameter, or any user-controllable part of the application that is passed into a server-side template without proper sanitization or escaping.

For example, the attacker might identify a web form, search bar, or template preview functionality that seems to return results based on dynamic user input.

TIP: Generated PDF files, invoices and emails usually use a template.

Inject Template Syntax

The attacker tests the identified input field by injecting template syntax specific to the template engine in use. Different web frameworks use different template engines (e.g., Jinja2 for Python, Twig for PHP, or FreeMarker for Java).

Common template expressions:

  • {{7*7}} for Jinja2 (Python).
  • #{7*7} for Thymeleaf (Java).

Find more template expressions in the page dedicated to the technology (PHP, Python, etc).

SSTI cheatsheet workflow

In most cases, this polyglot payload will trigger an error in presence of a SSTI vulnerability:

${{<%[%'"}}%\.

The Hackmanit/Template Injection Table is an interactive table containing the most efficient template injection polyglots along with the expected responses of the 44 most important template engines.

Enumerate the Template Engine

Based on the successful response, the attacker determines which template engine is being used. This step is critical because different template engines have different syntax, features, and potential for exploitation. The attacker may try different payloads to see which one executes, thereby identifying the engine.

  • Python: Django, Jinja2, Mako, ...
  • Java: Freemarker, Jinjava, Velocity, ...
  • Ruby: ERB, Slim, ...

The post "template-engines-injection-101" from @0xAwali summarize the syntax and detection method for most of the template engines for JavaScript, Python, Ruby, Java and PHP and how to differentiate between engines that use the same syntax.

Escalate to Code Execution

Once the template engine is identified, the attacker injects more complex expressions, aiming to execute server-side commands or arbitrary code.

Labs

References