SSTI Detection
Server-side template injection occurs when user input is embedded in a template string and evaluated by the template engine. The result is often remote code execution since template engines have access to Python, Java, or PHP internals. Detection confirms evaluation is happening — engine identification determines the exploitation payload. Confirmed SSTI moves to SSTI exploitation.
Target parameters that appear in rendered output: name, message, subject, query, template, search, greeting. Any parameter whose value appears reflected in the page is a candidate.
Initial Probe
Send a mathematical expression wrapped in template delimiters. If the result is evaluated rather than reflected literally, template injection is confirmed:
49
49
The response containing 49 instead of 49 confirms template evaluation. If the literal string 49 appears in the output, the template engine is not processing input or a different delimiter is needed.
Engine Identification
Different template engines use different delimiters and syntax. Use a decision payload to identify the engine:
7777777
Engine identification from the response:
Payload | Response | Engine |
|---|---|---|
49 | 49 | Jinja2, Twig, or other |
49 | 49 | Jinja2 (Python) |
49 | 7777777 | Twig (PHP) |
${7*7} | 49 | Freemarker or Thymeleaf (Java) |
#{7*7} | 49 | Ruby ERB or Pebble |
Test Multiple Delimiter Formats
If the standard Jinja2 delimiter does not work, try alternates used by other engines:
49 ->
${7*7} -> 49
#{7*7} ->
<%= 7*7 %> ->
[[7*7]] ->
{7*7} ->
${7*7} evaluating to 49 indicates a Java-based template engine. Use tplmap to automate engine identification and exploitation:
[+] Tplmap 0.5
[*] Testing if GET parameter 'name' is injectable
[+] Jinja2 plugin is testing rendering with tag '{{'
[+] Jinja2 rendered with tag '{{'
[+] Jinja2 is vulnerable!
References
-
Detection methodology and engine identification decision tree
-
Automated SSTI detection and exploitation tool
Was this helpful?
Your feedback helps improve this page.