Server-side template injection (SSTI) is a vulnerability where a server uses an attacker’s input to render a template but fails to sanitize the content provided, enabling the attacker to inject scripts or other malicious artifacts, enabling XSS attacks or remote code execution (RCE) once the template is rendered. Below is a good introduction to SSTI from OWASP:

Templating engine discovery

There are various templating engines for web technologies, some examples are:

Templating engineLanguageServer / client side
TwigPHPServer side
FreemarkerJavaServer side
Pug / JadeJavaScriptServer side
JinjaPythonServer side
HandlebarsJavaScriptBoth
MustacheMultipleVaries

Knowing what template engine we’re targeting is pivotal to successful exploitation. To discover the templating engine for a target we suspect is vulnerable to SSTI, follow their documentation and attempt to use engine-specific syntax to discover the target’s templating engine.

Code execution with Twig

Some features of Twig enable attackers to gain RCE on PHP servers using SSTI. Using filters that take functions as arguments, we can provide system as a function, and then our argument can be some bash command that will be executed on the host via PHP. For example, we use the reduce filter to read files on the host:

{{ [0]|reduce('system', 'cat /etc/passwd') }}

Code execution with Freemarker

Apache Freemarker is a templating engine commonly paired with Java applications. If an attacker can provide arbitrary input to a server rendering Apache Freemarker templates, attackers can gain RCE, e.g.:

${"freemarker.template.utility.Execute"?new()("cat /etc/passwd")}

Code execution with Pug

Pug is a templating engine for JavaScript and NodeJS, enabling the rendering of templates both on the client and server side. Pug is used to inject and generate HTML tags and content. Attackers can gain RCE on a NodeJS server rendering Pug templates by abusing the client_process.spawnSync method, e.g.:

- var require = global.process.mainModule.require
= exec = require('child_process').spawnSync('cat', ['/etc/passwd']).stdout

Leaking sensitive information from Jinja

Jinja is a templating engine for Python, primarily used for server-side rendering. Attackers can use template injection attacks to disclose sensitive information about a web application’s configuration, e.g.:

{{ config | pprint}}

The above Jinja template leaks the global Flask config value for the Jinja templating engine, and pretty prints the contents using the pprint filter.