# SSTI Jinja2 Template Injection RCE (Haystack Pipeline)

- **Severity:** High
- **Signature ID:** `7c3f9a2e-5b41-4d6c-9e08-2a1f6b84c37d`

## Summary

This detects command-line evidence that someone exploited a server-side template injection flaw in deepset Haystack (versions before 2.3.1) to run arbitrary code. It looks for the tell-tale combination of Jinja2 template syntax and Python's sandbox-escape trick showing up together in a spawned process.

## How the attack works

Haystack lets users build and run Pipelines that include components (PromptBuilder, OutputAdapter, ConditionalRouter) which render Jinja2 templates. An attacker submits a malicious template containing the classic Jinja2 sandbox-escape chain (__class__ -> __mro__ -> __subclasses__ -> __globals__/__import__) instead of normal input. When Haystack renders this template with the privileges of its own process, the payload re-enters a Python or shell interpreter, commonly via python -c, python -m, or sh -c, and the exploit text is carried verbatim into the resulting process command line. The detection fires only when Jinja2-style delimiters AND a dangerous Python construct both appear together in that command line — either alone is common in legitimate tooling.

## Why it matters

A successful exploit runs attacker-chosen code with the same privileges as the Haystack service, which can lead to data theft, further lateral movement, or full host compromise depending on what that process can access.

## What you can do

- Upgrade Haystack to 2.3.1 or later, or restrict who can submit custom Pipeline definitions.
- Do not let untrusted users control template strings fed into PromptBuilder, OutputAdapter, or ConditionalRouter.
- Run the Haystack process with the least privilege necessary, so a template-injection RCE has limited blast radius.
- Review any alerts for legitimate causes first — red-team SSTI testing, SAST scanners referencing gadget strings, or developers debugging Jinja2/CPython introspection can all trigger this pattern.

## Known benign look-alikes

- Security researchers or red teams executing SSTI proof-of-concept payloads against a local Haystack or Flask/Jinja2 instance — the command line is indistinguishable from a real exploit by design.
- SAST/secret scanners invoked with SSTI gadget strings as rule or pattern arguments; filtered when the scanner is argv[0], NOT filtered when wrapped in `sh -c "semgrep ..."`.
- Developer debugging of CPython introspection or Jinja2 sandbox behaviour, e.g. `python -c "print(().__class__.__mro__[1].__subclasses__())"` — only fires if an execution sink (os.system/subprocess/__import__) is also present in the same command line.
- CTF tooling, exploit-development scratch scripts, and security-training exercises run on developer workstations.
- Configuration management that renders Jinja braces around shell strings (ansible, consul-template, j2cli); filtered when the renderer is argv[0].
- Template-engine unit tests whose fixture payload is passed on the command line rather than read from a file.

## References

- https://github.com/deepset-ai/haystack/security/advisories
- https://github.com/deepset-ai/haystack/releases/tag/v2.3.1
- https://owasp.org/Top10/A03_2021-Injection/
- https://portswigger.net/web-security/server-side-template-injection

---
Source: https://www.netzilo.com/threats/haystack-jinja2-ssti-rce
