Welcome back to our cybersecurity journey. If you have been following our SQL Injection series, you are in for another exciting exploration today. We are diving into the world of Server-Side Template Injection (SSTI). Buckle up, and let’s jump in together.
Anyway, you can find our SQL Injection series and other interesting articles here.
Fundamentals of Template Engines and Templates
Firstly, it’s crucial to have understanding on template engines and templates.
What is template engines and templates?*
In web development, template engines are utilised to process templates, which are HTML files containing placeholders for dynamic content. These engines combine templates with data to produce fully rendered web pages. This separation of logic and presentation facilitates code reuse, ensures consistency, and improves scalability in web applications.
Basic Components of Templates
Templates consist of basic components that facilitate the insertion of dynamic content. These components include:
a. Variables
Variables serve as placeholders that are replaced with actual values during rendering. For instance, in the template below, variable {{ username }}
might be rendered as John
.
...
<h1>Hello, {{ username }}!</h1>
...
b. Expressions
Expressions allow for dynamic computation or manipulation of data. These expressions can include arithmetic operations, string concatenation, function calls and more. For instance, in the template below, expression {{ 2 + 2 }}
would evaluate to 4
.
...
<p>The result of 2 + 2 is: {{ 2 + 2 }}</p>
...
c. Control Structures
Control structures enable conditional logic and iteration within templates. These structure include if
statements, loops, and iterators, allowing developers to control the flow of content generation based on certain conditions.
...
{% if user.is_authenticated %}
<h1>Hello, {{ user.username }}!</h1>
{% else %}
<p>You are not a user, please sign up.</p>
{% endif %}
...
Overview of Common Template Engines
Next, let’s familiarise ourselves with some common template engines and their syntax differences.
a. Jinja2
Jinja2 is a popular templating engine for Python web development, inspired by Django. It offers a high level of flexibility and is widely used in frameworks like Flask and Django itself.
Syntax:
{% for item in items %}
<li>{{ item }}</li>
{% endfor %}
b. Handlebars
Handlebars is a logic-less templating engine for JavaScript, designed to build expressive templates efficiently. It’s commonly used in modern frameworks like Ember.js and Backbone.js.
Syntax:
{{#each items}}
<li>{{ this }}</li>
{{/each}}
c. ERB (Embedded Ruby)
ERB is a templating system for Ruby that embeds Ruby code into a text document. It’s commonly used in Ruby on Rails applications for generating dynamic HTML content.
Syntax:
<% items.each do |item| %>
<li><%= item %></li>
<% end %>
d. Smarty
Smarty is a template engine for PHP, designed to separate application logic from presentation logic. It provides a wide range of features for building dynamic web applications with PHP.
Syntax:
{foreach $items as $item}
<li>{$item}</li>
{/foreach}
It is worth noting that the above just some of the examples. There are many other template engines, such as Twig, Freemarker, and Mustache. Each of these engines has its own syntax, so it’s recommended to explore the documentation specific to each one.
Server-Side Template Injection
Now, let’s start our journey on the world of SSTI.
What is Server-Side Template Injection?
Server-Side Template Injection or SSTI is a specific example of template injection that occurs on the server side. It occurs when an application processes user inputs as templates on the server and evaluates them. If an attacker can inject malicious template expressions into ther server-side processing, they might gain the ability to execute code within the server’s context.
Example:
Consider a web application that has a template like below:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Welcome</title>
</head>
<body>
<h1>Hello, {{ username }}!</h1>
<p>Welcome to our website.</p>
</body>
</html>
The {{ username }}
part is the placeholder that will be replaced with a username when the page is rendered. But what if attackers manage to manipulate the variable and inject something like {{ 7*7 }}
? The possibilities become fascinating, and that’s where the adventure into SSTI begins.
What is the impact of SSTI?
The impact of SSTI can be severe and wide-ranging, posing significant risks to the security and integrity of web applications.
a. Remote Code Execution
SSTI vulnerabilities allow attackers to remotely execute arbitrary code on the server, leading to running system commands, file manipulation, compromising accounts and potentially gaining full server control.
b. Data Leakage
Even if RCE is not possible, attackers can still leverage SSTI vulnerabilities to access sensitive information like database contents, configuration files and environment variables. This data can be exploited for further attacks.
How does SSTI looks like?
Enough theories, let’s illustrate this with a simple scenario from PortSwigger Academy.
Resources: PortSwigger: SSTI - File Deletion
Scenario:
Exploiting SSTI vulnerability in ERB template to delete file
This lab is vulnerable to Server-Side Template Injection due to the unsafe construction of an ERB template.
To solve the lab, review the ERB documentation to find out how to execute arbitrary code, then delete themorale.txt
file from Carlos’s home directory.
After gaining access to the lab, we were greeted with an e-commerce home page featuring various products.
However, upon attempting to view more details about the first product, we encountered a different behavior.
A GET request was made, using the message
parameter, leading to the display of the message “Unfortunately this product is out of stock” on the home page.
Realising the potential for manipulation, we use Burp Suite Repeater for the interception and modification of request. With this, we could inject payloads into the message
parameter to investigate further.
According to ERB documentation, content within an ERB template is treated as HTML, unless specified otherwise using special tags.
This <%= EXPRESSION %>
tag is used to evaluate the given expression and directly output the result into the rendered template.
Hence, we utilise this syntax to create an expression containing a mathematical operation to verify if the payload is being executed. For this testing, we used this payload <%= 7*7 %>
.
Request URL: https://burp-academy/?message=<%= 7*7 %>
Upon sending the request, we observed the result of our mathematical operation, 49, was displayed on the page. This indicates a potential server-side template injection vulnerability.
Further exploration into the Ruby documentation, we discovered that the system()
can be used to execute arbitrary operating system commands.
To confirm our identity within the system, we constructed a payload using system("whoami")
. The response confirmed that we were indeed ‘Carlos’, providing valuable insight to achieve the lab’s objective.
Request URL: https://burp-academy/?message=<%= system("whoami") %>
Continuing our exploitation, we utilised system("pwd")
to determine our current directory, revealing that we were situated in Carlos’s home directory.
Request URL: https://burp-academy/?message=<%= system("pwd") %>
Then, we discovered the presence of a file named ‘morale.txt’ within the directory. This was confirmed by utilising the system("ls")
command.
Request URL: https://burp-academy/?message=<%= system("ls") %>
Finally, to achieve the lab’s objective, we executed a payload to delete the ‘morale.txt’ file using system("rm morale.txt")
.
Request URL: https://burp-academy/?message=<%= system("rm morale.txt") %>
By successfully removing the file, we accomplished the lab’s objective.
How to prevent from SSTI vulnerabilities?
Lastly, let’s take a look on how to prevent our applications from SSTI.
a. Access control
A fundamental approach is to restrict access to template files, as open-access templates are easy targets for attackers.
By implementing strict rules that permit only developers and administrators to modify templates, we can reduce the risk of attacks.
b. Input sanitisation
Sanitising inputs is crucial to mitigate SSTI risks. Templates must validate input data, allowing only expected elements. Regular expressions can help to define allowed patterns.
However, input sanitisation has its limits, attackers may find ways to bypass it and potentially exposing vulnerabilities.
c. Sandboxing
Sandboxing offers a stronger defense than input sanitisation by creating a secure, isolated environment with restricted user actions. It prohibits access to risky functions or modules, minimising attack impact.
However, implementing sandboxing is complex, and attackers may exploit misconfigurations or attempt privilege escalation to bypass it.
d. Logic-less templates
A highly secure method involves employing logic-less templates, which separate the process of interpreting code from how it is displayed visually on a webpage.
For example, in Handlebars and Mustache, control flow statements rely on provided data, not executable code which reduces the risk of remote code execution and enhances security.
That concludes the first article in this series. We hope you have gained valuable insights from this post. Stay tuned for the next articles.
Thank you.
References: