What is template injection?

We are happy to welcome you back to our blog series where we are shedding light on the most interesting and useful insights about top reported vulnerabilities. In this blog we will talk about Template Injection vulnerability, and discuss where the vulnerability can be found, what types of this vulnerability are there, what is the impact, severity and ways how vulnerability can be prevented and mitigated.

What is template injection?

Template injection is a vulnerability in web applications where input is evaluated as code by a templating engine. 

Template engines are used in web applications to automatically generate web pages, such as the results from a search. This reuses static web page elements while defining dynamic elements based on web request parameters. 

For example, a profile settings page of a web application might use a template where it dynamically fills in the users’ information. The page will mostly be the same for everyone, but user-specific information will be dynamically filled in based on the logged-in user.

To find a template injection vulnerability an attacker will try to see how an input field reacts to template expressions, if the code is evaluated the output will be different from what the attacker entered into the field. When entering {{7*’7’}} Twig and Jinja2 react differently. In Jinja2 this would result in 7777777 and in Twig the result is 49.

If the response is reflected somewhere on the page the attacker can test whether template injection is possible and often determine which template engine is used. The following example is a simple page that displays a user’s information.

By inserting different payloads it can be found that the page is vulnerable to template injection. It can also be detected that the template engine used is Jinja2 by the way it reacts to the {{7*’7’}} payload.

There are two different types of template injection, server side and client side. With client side template injection (CSTI) an attacker is able to execute code in the browser. Template injection with server side (SSTI), is when the code is executed on the server.

Template injection vulnerabilities are present in, but not limited to the following templating engines:

  • PHP: Smarty, Twig.
  • Java: Velocity, Freemaker.
  • Python: Jinja2, Mako, Tornado.

Impact

Server side

Remote code execution
When a template injection executes code server side it may be possible to achieve remote code execution depending on the template engine used. Another possible impact of SSTI is retrieving files from the server using local file inclusion.

Information disclosure
An adversary can use template injection to gain sensitive information, for instance by reading the content of variables or inserting commands that disclose information. By inserting {{config.items()}} in the example page the configuration details can be displayed.

Client side

Cross-site scripting
When code is executed with a template injection vulnerability it can be possible to inject JavaScript to create an XSS vulnerability. This is possible with both server side and client side template injection. This gives a template injection vulnerability the same impact that XSS can have. For example:

  • Stealing session cookies.
  • Steal login credentials.
  • Gain access to sensitive information.

Severity

The severity of a template injection vulnerability depends on the impact. SSTI will have a higher impact than CSTI. 

Any vulnerability that can achieve remote code execution will have a critical severity.

An example of high or medium-severity template injection is when the template injection can be elevated to XSS. Reflected XSS has a medium severity and stored XSS often has a high severity.

When client side template injection is present but no information can be retrieved and it can’t be elevated to XSS the severity is low.

Prevention

To prevent template injection input can be filtered to stop it from being rendered as code. The following characters are often used when testing for template injection: ${{<%[%’”}}%\. It is also possible to allowlist input and only allow expected input.

Mitigation

If it is not possible to filter input you can sometimes sandbox the template limiting the actions possible when injecting code with template injection.
Because template injection is a known problem in template engines, many offer sandboxing possibilities. For example in Twig, a PHP template engine, the sandbox tag can be used for an included template.
Example: 

{% sandbox %}
{% include 'user.html' %}
{% endsandbox %}

We hope you find the information useful and enjoyed the blog! If you did, stay tuned for the next blog on top reported vulnerabilities!

More information