# Template Injection

In web design, a *template* is an HTML-like file interspersed with programmatic instructions to be interpreted by the web-server or JavaScript code in the browser at runtime. A template is a *static* file used to generate HTML by interpolating *dynamic* content retrieved from a database or pulled from HTTP.

A **template injection** vulnerability occurs when the dynamic content is treated by the template engine as code to be executed rather data to be interpolated. This will allow an attacker to execute malicious code on your server or in a victim’s browser.

## Template Injection in Python

There’s a wide variety of templating engines in Python. Jinja2 (the default engine for the Flask web-server) is one of the most popular, and allows easy interpolation of data into HTML. Template files can be loaded from disk, or template strings can be constructed dynamically. The latter scenario presents some risks:

from flask import Flask, render_template_stringapp = Flask(__name__)

def profile_data(username, field):
user = load_profile(username)

return render_template_string(“””
<h1> {{ username }} </h1>
<p> {{ “”” + field + “”” }} </p>
“””, username=username, field=user.get(field, ‘No data’))

This function is intended to take a path like `/users/username/email` and look up the “email” field on that particular user. However, since the third part of the path is concatenated into the template string (notice the `+` characters), a URL like `/user/username/5*5` will print out “25” – the `field` parameter will get evaluated as code at runtime. Performing a simple arithmetic calculation is the least of your worries here – a smart attacker will be able to figure out how to run commands on your underlying operating system with a little experimentation.

## Mitigation

To protect against template injection attacks, ensure your templates are statically defined, rather than generated by string concatenation at runtime. A good way to achieve this is to have the templates defined as files on disk:

from flask import Flask, render_templateapp = Flask(__name__)

def profile_data(username, field):
user = load_profile(username)

# Since the template is loaded from disk, we can be sure it is statically defined.
return render_template(‘profile.html’,
username = username,
field = user.get(field, ‘No data’))

## CWEs

* [CWE-94](https://cwe.mitre.org/data/definitions/94.html)

About ShiftLeft

ShiftLeft empowers developers and AppSec teams to dramatically reduce risk by quickly finding and fixing the vulnerabilities most likely to reach their applications and ignoring reported vulnerabilities that pose little risk. Industry-leading accuracy allows developers to focus on security fixes that matter and improve code velocity while enabling AppSec engineers to shift security left.

A unified code security platform, ShiftLeft CORE scans for attack context across custom code, APIs, OSS, containers, internal microservices, and first-party business logic by combining results of the company’s and Intelligent Software Composition Analysis (SCA). Using its unique graph database that combines code attributes and analyzes actual attack paths based on real application architecture, ShiftLeft then provides detailed guidance on risk remediation within existing development workflows and tooling. Teams that use ShiftLeft ship more secure code, faster. Backed by SYN Ventures, Bain Capital Ventures, Blackstone, Mayfield, Thomvest Ventures, and SineWave Ventures, ShiftLeft is based in Santa Clara, California. For information, visit: www.shiftleft.io.


See for yourself – run a scan on your code right now