A Pentester’s Guide to Server Side Template Injection (SSTI)
Basics of SSTI
Before diving into Server-Side Template Injection (SSTI), it’s important to understand the basics of web application template engines.
What is Template Engines
Templating engines can accept a generic document, known as a template, and combine it with a set of variables to create a final document.For example, let’s review an email that an administrator wants to send to their customers.
While it’s possible for the administrator to create a custom email for every order, it is much more convenient to create a template that can be reused multiple times as below example
Various Template Engines
Templating Engine | Language | Server/client Side |
Twig,Smarty | PHP | Server Side |
Freemarker,Velocity | Java (usually) | Server Side |
Pug/Jade | JavaScript | Mostly Server Side |
Jinja,Mako,Tornado | Python | Server Side |
Handlebars | JavaScript | Both |
Liquid | Ruby | Varies |
What is Server-side template injection?
A Server-side Template Injection (SSTI) is a security vulnerability that occurs when an attacker is able to inject malicious code into a template using built-in template language constructs. The injected code is then executed on the server-side, which can lead to the compromise of sensitive data or the entire system.
SSTI methodology steps
- Look for Reflection of our User-controlled input.
- If our payload is evaluated, Enumerate the templating Engine.
- We have 2 ways to identify which templating Engine is the website using.
1. Through Error message(Stack trace)
- Use the polyglot payload as the value of the parameter which is a sequence of special characters such as the following:
It will generate the following error. Based on the below picture we can easily identify that the website is using the django framework.
2. To supply mathematical expressions in curly brackets. Based on the observed rendering of payloads, narrow down the testing to specific template engines that match the observed behaviour.
For example, if the payload #{ 9 * 9 } render as 81, focus on testing for template engines like freemarker (legacy), slim template engine in Ruby, Markaby, Erector HAML (older versions), or the PugJS template engine in Node.js.
SSTI in Smarty(PHP):
We can use the given payloads if we have identified that the application is using smarty template engine. We can use functions like system, passthru, shell_exec and exec in PHP which allows us to execute system commands.
SSTI in Ruby ERB:
We can use the given payloads if we have identified that the application is using ERB template engine.
How to Prevent SSTI?
- Input Validation and Sanitization
- Use of Safe Templating Engines
- Code Reviews and Testing
- Keep the Server and Dependencies Up-to-date