Skip to content

Payloads · Command and Code Injection

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.

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.

Disclosed reports of this class

126 of 126 passages

Passages
  1. Server Side Template Injection
  2. Tools
  3. Detection and Exploitation Techniques
  4. Rendered
  5. Error-Based
  6. Boolean-Based
  7. Time-Based
  8. Out of Bounds
  9. Polyglot-Based
  10. Universal Detection Payloads
  11. Identify the Vulnerable Input Field
  12. Inject Template Syntax
  13. Enumerate the Template Engine
  14. Escalate to Code Execution
  15. ASP: Server Side Template Injection - ASP.NET
  16. ASP: ASP.NET Razor
  17. ASP: ASP.NET Razor - Basic Injection
  18. ASP: ASP.NET Razor - Command Execution
  19. Elixir: Server Side Template Injection - Elixir
  20. Elixir: Templating Libraries
  21. Elixir: Universal Payloads
  22. Elixir: EEx
  23. Elixir: EEx - Basic injections
  24. Elixir: EEx - Retrieve /etc/passwd
  25. Elixir: EEx - Remote Command execution
  26. Java: Server Side Template Injection - Java
  27. Java: Templating Libraries
  28. Java: Java EL - Basic Injection
  29. Java: Java EL - Code Execution
  30. Java: Freemarker
  31. Java: Freemarker - Basic Injection
  32. Java: Freemarker - Read File
  33. Java: Freemarker - Code Execution
  34. Java: Freemarker - Code Execution with Obfuscation
  35. Java: Freemarker - Sandbox Bypass
  36. Java: Jinjava
  37. Java: Jinjava - Basic Injection
  38. Java: Jinjava - Command Execution
  39. Java: Pebble
  40. Java: Pebble - Basic Injection
  41. Java: Pebble - Code Execution
  42. Java: Velocity
  43. Java: Groovy
  44. Java: Groovy - Basic injection
  45. Java: Groovy - Read File
  46. Java: Groovy - HTTP Request
  47. Java: Groovy - Command Execution
  48. Java: Groovy - Command Execution with Obfuscation
  49. Java: Groovy - Sandbox Bypass
  50. Java: Spring Expression Language
  51. Java: SpEL - Basic Injection
  52. Java: SpEL - Retrieve Environment Variables
  53. Java: SpEL - Retrieve /etc/passwd
  54. Java: SpEL - DNS Exfiltration
  55. Java: SpEL - Session Attributes
  56. Java: SpEL - Command Execution
  57. Java: Object-Graph Navigation Language
  58. Java: OGNL - Basic Injection
  59. Java: OGNL - Command Execution
  60. JavaScript: Server Side Template Injection - JavaScript
  61. JavaScript: Templating Libraries
  62. JavaScript: Universal Payloads
  63. JavaScript: Handlebars
  64. JavaScript: Handlebars - Basic Injection
  65. JavaScript: Handlebars - Command Execution
  66. JavaScript: Lodash
  67. JavaScript: Lodash - Basic Injection
  68. JavaScript: Lodash - Command Execution
  69. JavaScript: Pug
  70. PHP: Server Side Template Injection - PHP
  71. PHP: Templating Libraries
  72. PHP: Universal Payloads
  73. PHP: Blade
  74. PHP: Smarty
  75. PHP: Smarty - Code Execution with Obfuscation
  76. PHP: Twig
  77. PHP: Twig - Basic Injection
  78. PHP: Twig - Template Format
  79. PHP: Twig - Arbitrary File Reading
  80. PHP: Twig - Code Execution
  81. PHP: Twig - Code Execution with Obfuscation
  82. PHP: Latte
  83. PHP: Latte - Basic Injection
  84. PHP: Latte - Code Execution
  85. PHP: patTemplate
  86. PHP: PHPlib and HTMLTemplatePHPLIB
  87. PHP: Plates
  88. Python: Server Side Template Injection - Python
  89. Python: Templating Libraries
  90. Python: Universal Payloads
  91. Python: Django
  92. Python: Django - Basic Injection
  93. Python: Django - Cross-Site Scripting
  94. Python: Django - Debug Information Leak
  95. Python: Django - Leaking App's Secret Key
  96. Python: Django - Admin Site URL leak
  97. Python: Django - Admin Username And Password Hash Leak
  98. Python: Jinja2
  99. Python: Jinja2 - Basic Injection
  100. Python: Jinja2 - Template Format
  101. Python: Jinja2 - Debug Statement
  102. Python: Jinja2 - Dump All Used Classes
  103. Python: Jinja2 - Dump All Config Variables
  104. Python: Jinja2 - Read Remote File
  105. Python: Jinja2 - Write Into Remote File
  106. Python: Jinja2 - Remote Command Execution
  107. Python: Jinja2 - Forcing Output On Blind RCE
  108. Python: Exploit The SSTI By Calling os.popen().read()
  109. Python: Exploit The SSTI By Calling subprocess.Popen
  110. Python: Exploit The SSTI By Calling Popen Without Guessing The Offset
  111. Python: Exploit The SSTI By Writing An Evil Config File
  112. Python: Jinja2 - Remote Command Execution with Obfuscation
  113. Python: Jinja2 - Filter Bypass
  114. Python: Tornado
  115. Python: Tornado - Basic Injection
  116. Python: Tornado - Remote Command Execution
  117. Python: Mako
  118. Python: Mako - Remote Command Execution
  119. Python: Mako - Remote Command Execution with Obfuscation
  120. Ruby: Server Side Template Injection - Ruby
  121. Ruby: Templating Libraries
  122. Ruby: Universal Payloads
  123. Ruby: Ruby - Basic injections
  124. Ruby: Ruby - Retrieve /etc/passwd
  125. Ruby: Ruby - List files and directories
  126. Ruby: Ruby - Remote Command execution

Server Side Template Injection

SourceOn the Atlas

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

Tools

SourceOn the Atlas

- [Hackmanit/TInjA](https://github.com/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](https://github.com/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](https://github.com/vladko312/SSTImap) - Automatic SSTI detection tool with interactive interface based on [epinna/tplmap](https://github.com/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'

Detection and Exploitation Techniques

SourceOn the Atlas

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)

Rendered

SourceOn the Atlas

![Rendered technique workflow](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Template%20Injection/Images/technique_Rendered.png?raw=true) > 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

SourceOn the Atlas

![Error-Based technique workflow](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Template%20Injection/Images/technique_Error-Based.png?raw=true) > 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

SourceOn the Atlas

![Boolean-Based technique workflow](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Template%20Injection/Images/technique_Boolean-Based.png?raw=true) > 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

SourceOn the Atlas

![Time-Based technique workflow](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Template%20Injection/Images/technique_Time-Based.png?raw=true) > 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

SourceOn the Atlas

> 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

SourceOn the Atlas

![Polyglot-Based technique workflow](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Template%20Injection/Images/technique_Polyglot-Based.png?raw=true) > Applicability: detection Polyglot-Based technique can be used to quickly determine the template engine by checking how it transforms different payloads.

Universal Detection Payloads

SourceOn the Atlas

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.

Identify the Vulnerable Input Field

SourceOn the Atlas

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

SourceOn the Atlas

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](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Template%20Injection/Images/serverside.png?raw=true) 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.

Enumerate the Template Engine

SourceOn the Atlas

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.

Escalate to Code Execution

SourceOn the Atlas

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

ASP: Server Side Template Injection - ASP.NET

SourceOn the Atlas

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

ASP: ASP.NET Razor

SourceOn the Atlas

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

Elixir: Server Side Template Injection - Elixir

SourceOn the Atlas

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

Elixir: Templating Libraries

SourceOn the Atlas

| Template Name | Payload Format | |---------------|----------------| | EEx | `<%= %>` | | LEEx | `<%= %>` | | HEEx | `<%= %>` |

Data as of 2026-11-14.

Updated AboutDevelopersSign in