Skip to main content

Detect and neutralize Jinja2 server-side template injection (SSTI) payloads

Project description

jinja2-ssti-sanitizer

Detect and neutralize Jinja2 server-side template injection (SSTI) payloads before they reach your templates.

CI PyPI version

Installation

pip install jinja2-ssti-sanitizer

For safe rendering helpers that use Jinja2's SandboxedEnvironment:

pip install jinja2-ssti-sanitizer[render]

Quick start

from jinja2_ssti_sanitizer import (
    is_jinja2_payload,
    sanitize_jinja2_input,
    render_safely,
)

# Detect SSTI attempts in user input
if is_jinja2_payload(user_input):
    raise ValueError("blocked")

# Escape delimiters and strip gadget fragments
result = sanitize_jinja2_input(user_input)
safe_text = result.sanitized

# Render a fixed template with a validated context
html = render_safely("Hello {{ name }}!", {"name": user_name})

API

Function Description
detect_threats(value) Returns threat level and matched rule names
is_jinja2_payload(value) True when input matches SSTI patterns
sanitize_jinja2_input(value, mode="escape") Neutralize input (escape, strip, or reject)
validate_template_variable(name, value) Validate a single context value
validate_template_context(context) Validate all string values in a render context
create_safe_environment() SandboxedEnvironment with safe defaults
render_safely(template_source, context) Render with validated context

Sanitization modes

  • escape (default) — HTML-entity-encode {{, }}, {%, %}, {#, #} and strip gadget fragments
  • strip — remove delimiter tokens and dangerous expressions
  • reject — raise ValueError on HIGH or CRITICAL threats

Critical payloads (dunder chains, mro, subclasses, import/include tags, etc.) are always rejected when reject_critical=True (the default).

What it protects against

  • Jinja2 variable, block, and comment delimiters
  • Common gadget chains (__class__, mro, subclasses, config, request, attr filter, …)
  • Unicode homoglyphs and zero-width bypass characters

Defense in depth

This library is a input-validation layer, not a substitute for secure design:

  1. Never build template source from user-controlled input.
  2. Use SandboxedEnvironment with autoescape enabled.
  3. Sanitize or reject untrusted strings before they enter template context.

Development

git clone https://github.com/kjsxz/sanitizer-library.git
cd sanitizer-library
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
pytest
python -m build

Publishing to PyPI

Releases are published automatically when a GitHub Release is created.

One-time setup

  1. Create a PyPI project at pypi.org (or test.pypi.org first).
  2. Configure trusted publishing on PyPI:
    • Publisher: GitHub Actions
    • Repository: kjsxz/sanitizer-library
    • Workflow: publish.yml
    • Environment: pypi
  3. In GitHub repo settings, create an environment named pypi (optional approval gate).

Release flow

# Bump version in pyproject.toml and jinja2_ssti_sanitizer/__init__.py
git tag v0.1.0
git push origin v0.1.0

Then create a GitHub Release from the tag. The publish workflow uploads to PyPI.

Manual publish (maintainers):

pip install build twine
python -m build
twine upload dist/*

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

jinja2_ssti_sanitizer-0.1.0.tar.gz (7.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

jinja2_ssti_sanitizer-0.1.0-py3-none-any.whl (7.9 kB view details)

Uploaded Python 3

File details

Details for the file jinja2_ssti_sanitizer-0.1.0.tar.gz.

File metadata

  • Download URL: jinja2_ssti_sanitizer-0.1.0.tar.gz
  • Upload date:
  • Size: 7.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for jinja2_ssti_sanitizer-0.1.0.tar.gz
Algorithm Hash digest
SHA256 838d64752a3c461a8d0916693d0a88cac2d89af3f61b500eb7aed555e8eb253e
MD5 a72011cecd14571385b26115b65fe1bd
BLAKE2b-256 ff842efc246efee0e09153d8787e4c17529f01e2b164c5886fb81c3002df4c4e

See more details on using hashes here.

Provenance

The following attestation bundles were made for jinja2_ssti_sanitizer-0.1.0.tar.gz:

Publisher: publish.yml on kjsxz/sanitizer-library

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file jinja2_ssti_sanitizer-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for jinja2_ssti_sanitizer-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e11ab710562e6a76e3088432249bd399bead923afeba65eef5c1084529196e5c
MD5 f8ab5544e0495cbf6636cb43aae46da5
BLAKE2b-256 9bc7f227be79390c531db503213970772f92e7eaa70c2cdb847d31375f46c6d8

See more details on using hashes here.

Provenance

The following attestation bundles were made for jinja2_ssti_sanitizer-0.1.0-py3-none-any.whl:

Publisher: publish.yml on kjsxz/sanitizer-library

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page