SSTI
CWE-1336: Improper Neutralization of Special Elements Used in a Template Engine
Last updated
CWE-1336: Improper Neutralization of Special Elements Used in a Template Engine
Last updated
Server-side template injection | Web Security Academy
What is server-side template injection?
Server-side template injection is when an attacker is able to use native template syntax to inject a malicious payload into a template, which is then executed server-side.
Template engines are designed to generate web pages by combining fixed templates with volatile data. Server-side template injection attacks can occur when user input is concatenated directly into a template, rather than passed in as data. This allows attackers to inject arbitrary template directives in order to manipulate the template engine, often enabling them to take complete control of the server. As the name suggests, server-side template injection payloads are delivered and evaluated server-side, potentially making them much more dangerous than a typical client-side template injection.
What is the impact of server-side template injection?
Server-side template injection vulnerabilities arise when user input is concatenated into templates rather than being passed in as data.
Static templates that simply provide placeholders into which dynamic content is rendered are generally not vulnerable to server-side template injection. The classic example is an email that greets each user by their name, such as the following extract from a Twig template:
This is not vulnerable to server-side template injection because the user's first name is merely passed into the template as data.
However, as templates are simply strings, web developers sometimes directly concatenate user input into templates prior to rendering. Let's take a similar example to the one above, but this time, users are able to customize parts of the email before it is sent. For example, they might be able to choose the name that is used:
In this example, instead of a static value being passed into the template, part of the template itself is being dynamically generated using the GET
parameter name
. As template syntax is evaluated server-side, this potentially allows an attacker to place a server-side template injection payload inside the name
parameter as follows:
Vulnerabilities like this are sometimes caused by accident due to poor template design by people unfamiliar with the security implications. Like in the example above, you may see different components, some of which contain user input, concatenated and embedded into a template. In some ways, this is similar to SQL injection vulnerabilities occurring in poorly written prepared statements.
However, sometimes this behavior is actually implemented intentionally. For example, some websites deliberately allow certain privileged users, such as content editors, to edit or submit custom templates by design. This clearly poses a huge security risk if an attacker is able to compromise an account with such privileges.
Work flow
Detect
try fuzzing the template by injecting a sequence of special characters commonly used in template expressions, such as ${{<%[%'"}}%\\
Identify
Exploit
https://portswigger.net/web-security/server-side-template-injection/exploiting
How to prevent server-side template injection vulnerabilities
The best way to prevent server-side template injection is to not allow any users to modify or submit new templates. However, this is sometimes unavoidable due to business requirements.
One of the simplest ways to avoid introducing server-side template injection vulnerabilities is to always use a "logic-less" template engine, such as Mustache, unless absolutely necessary. Separating the logic from presentation as much as possible can greatly reduce your exposure to the most dangerous template-based attacks.
Another measure is to only execute users' code in a sandboxed environment where potentially dangerous modules and functions have been removed altogether. Unfortunately, sandboxing untrusted code is inherently difficult and prone to bypasses.
Finally, another complementary approach is to accept that arbitrary code execution is all but inevitable and apply your own sandboxing by deploying your template environment in a locked-down Docker container, for example
SSTI Identified Using SSTImap
SSTI can be identified using the tool
SSTImap
. The limitations of this tool is that the template expression{{7*7}}
results are sometimes only evaluated by anotherGET request
or calling another function in the application, as the output is not directly reflected or echoed into the response where the template expression was posted.
POST request with the data
param
to test and send payload usingSSTImap
tool.
SSTI payloads to manually identify vulnerability. → Security-Hub/ssti.txt at main · M8SZT8/Security-Hub (github.com)
Exploit
Construct a payload to delete Carlos's file
<%= system("rm /home/carlos/morale.txt") %>
{{settings.SECRET_KEY}} ``` - Exploit - ssti to rce https://medium.com/r3d-buck3t/rce-with-server-side-template-injection-b9c5959ad31e