SSTI

PRACTICE ! PRACTICE ! PRACTICE !

Now that we've exploited the application, let's see what was actually happening in the backend

# Raw code 
template = f"<h1> Welcome to the profile of {user}! </h1>" 

# Code after injecting my name
template = f"<h1> Welcome to the profile of Akash! </h1>" 

# Code after injecting this payload {{ 7 * 7 }} 
template = f"<h1> Welcome to the profile of 49! </h1>"

So how do we mitigate this now ?

Secure methods

Most template engines will have a feature that allows you to pass input in as data, rather that concatenating input into the template

In Jinja2, this can be done by using the second argument

# Insecure code 
template = f"<h1> Welcome to the profile of {user}! </h1>" 
return render_template_string(template)

# Secure code 
template = "<h1> Welcome to the profile of {{ user }}! </h1>" 
return render_template_string(template, user=user)

Sanitisation

User Input cannot be trusted and is very dangerous, every place in your application where a user is allowed to add custom content, make sure the input is sanitised !

This can be done by first planning what character set you want to allow, and adding these to a whitelist, basically implementing Regex

import re 

# Remove everything that isn't alphanumeric 
user = re.sub("^[A-Za-z0-9]", "", user) 

template = "<h1> Welcome to the profile of {{ user }}! </h1>" 
return render_template_string(template, user=user)

Remember to read the documentation of the template engine you are using

Last updated