Testing for Server-side Template Injection (WSTG-INPV-18)
Last updated
Last updated
WSTG-INPV-18
Web applications commonly use server-side templating technologies (Jinja2, Twig, FreeMaker, etc.) to generate dynamic HTML responses. Server-side Template Injection vulnerabilities (SSTI) occur when user input is embedded in a template in an unsafe manner and results in remote code execution on the server. Any features that support advanced user-supplied markup may be vulnerable to SSTI including wiki-pages, reviews, marketing applications, CMS systems etc. Some template engines employ various mechanisms (eg. sandbox, allow listing, etc.) to protect against SSTI.
The following example is an excerpt from the Extreme Vulnerable Web Application project.
In the getFilter function the call_user_func($callback, $name)
is vulnerable to SSTI: the name
parameter is fetched from the HTTP GET request and executed by the server:
Figure 4.7.18-1: SSTI XVWA Example
The following example uses Flask and Jinja2 templating engine. The page
function accepts a 'name' parameter from an HTTP GET request and renders an HTML response with the name
variable content:
This code snippet is vulnerable to XSS but it is also vulnerable to SSTI. Using the following as a payload in the name
parameter:
Detect template injection vulnerability points.
Identify the templating engine.
Build the exploit.
SSTI vulnerabilities exist either in text or code context. In plaintext context users allowed to use freeform 'text' with direct HTML code. In code context the user input may also be placed within a template statement (eg. in a variable name)
The first step in testing SSTI in plaintext context is to construct common template expressions used by various template engines as payloads and monitor server responses to identify which template expression was executed by the server.
Common template expression examples:
In this step an extensive template expression test strings/payloads list is recommended.
Testing for SSTI in code context is slightly different. First, the tester constructs the request that result either blank or error server responses. In the example below the HTTP GET parameter is inserted info the variable personal_greeting
in a template statement:
Using the following payload - the server response is blank "Hello":
In the next step is to break out of the template statement and injecting HTML tag after it using the following payload
Based on the information from the previous step now the tester has to identify which template engine is used by supplying various template expressions. Based on the server responses the tester deduces the template engine used. This manual approach is discussed in greater detail in this PortSwigger article. To automate the identification of the SSTI vulnerability and the templating engine various tools are available including Tplmap or the Backslash Powered Scanner Burp Suite extension.
The main goal in this step is to identify to gain further control on the server with an RCE exploit by studying the template documentation and research. Key areas of interest are:
For template authors sections covering basic syntax.
Security considerations sections.
Lists of built-in methods, functions, filters, and variables.
Lists of extensions/plugins.
The tester can also identify what other objects, methods and properties can be exposed by focusing on the self
object. If the self
object is not available and the documentation does not reveal the technical details, a brute force of the variable name is recommended. Once the object is identified the next step is to loop through the object to identify all the methods, properties and attributes that are accessible through the template engine. This could lead to other kinds of security findings including privilege escalations, information disclosure about application passwords, API keys, configurations and environment variables, etc.