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.
For testing systems you own or are authorised to test, and for defending them. Nothing here is run by this page.
From PayloadsAllTheThings by Swissky and contributors. MIT License, Copyright (c) 2019 Swissky. The repository.
> 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.
- [vladko312/SSTImap](https://github.com/vladko312/SSTImap) - Automatic SSTI detection tool with interactive interface based on [epinna/tplmap](https://github.com/epinna/tplmap)
Original research:
- Rendered, Time-Based: [Server-Side Template Injection: RCE For The Modern Web App - James Kettle - August 05, 2015](https://portswigger.net/knowledgebase/papers/serversidetemplateinjection.pdf)
- Polyglot-Based: [Improving the Detection and Identification of Template Engines for Large-Scale Template Injection Scanning - Maximilian Hildebrand - September 19, 2023](https://www.hackmanit.de/images/download/thesis/Improving-the-Detection-and-Identification-of-Template-Engines-for-Large-Scale-Template-Injection-Scanning-Maximilian-Hildebrand-Master-Thesis-Hackmanit.pdf)
- Error-Based, Boolean-Based: [Successful Errors: New Code Injection and SSTI Techniques - Vladislav Korchagin - January 03, 2026](https://github.com/vladko312/Research_Successful_Errors/blob/main/README.md)

> 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.

> 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.

> 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.

> 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.
> 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.

> Applicability: detection
Polyglot-Based technique can be used to quickly determine the template engine by checking how it transforms different payloads.
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.
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.
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).

In most cases, this polyglot payload will trigger an error in presence of a SSTI vulnerability:
${{<%[%'"}}%\.
The [Hackmanit/Template Injection Table](https://github.com/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.
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](https://medium.com/@0xAwali/template-engines-injection-101-4f2fe59e5756) 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.
> Server-Side Template Injection (SSTI) is a class of vulnerabilities where an attacker can inject malicious input into a server-side template, causing the template engine to execute arbitrary code on the server. In the context of ASP.NET, SSTI can occur if user input is directly embedded into a template (such as Razor, ASPX, or other templating engines) without proper sanitization.
[Official website](https://docs.microsoft.com/en-us/aspnet/web-pages/overview/getting-started/introducing-razor-syntax-c)
> Razor is a markup syntax that lets you embed server-based code (Visual Basic and C#) into web pages.
> Server-Side Template Injection (SSTI) is a vulnerability that arises when an attacker can inject malicious code into a server-side template, causing the server to execute arbitrary commands. In Elixir, SSTI can occur when using templating engines like EEx (Embedded Elixir), especially when user input is incorporated into templates without proper sanitization or validation.