Skip to main content
CybersecurityVulnerability Management

LiteLLM Vulnerability Chain Enables Low-Privilege Server Takeover

Server equipment sits in a dimly lit data center with ordinary indoor lighting.

“Obsidian rates the full chain CVSS 9.9, in the Critical range.” That blunt assessment captures the practical danger: a default low‑privilege account on a widely used LiteLLM proxy can be escalated to full admin and run code on the server by chaining three distinct vulnerabilities.

CVE-2026-47101, CVE-2026-47102, and CVE-2026-40217 — how the chain works

Researchers at Obsidian Security disclosed a three‑bug escalation that begins with an authorization bypass, CVE-2026-47101. When an internal_user generates a virtual API key, LiteLLM stored the caller‑supplied allowed_routes field without checking it against the user’s role. That field was intended to narrow a key’s scope; instead the proxy treated it as a fallback grant. A non‑admin could therefore mint a key with allowed_routes: ["/*"], a wildcard that reaches every route — including admin‑only endpoints. The same unchecked write occurred across key‑management endpoints, which required multiple pull requests to fix.

With admin routes reachable, two further weaknesses become exploitable. CVE-2026-47102 is a privilege escalation through /user/update: the endpoint allows users to edit their own record but imposes no restriction on which fields can be written. A self‑update with user_role: "proxy_admin" was accepted and saved, promoting the caller to full proxy admin. VulnCheck assigned scores of 8.7 (CVSS 4.0) and 8.8 (CVSS 3.1) to that CVE.

The other linked issue, CVE-2026-40217, is a sandbox escape in the Custom Code Guardrail. LiteLLM’s production endpoints compiled and ran admin‑supplied Python through exec() with no source‑level filtering. When exec() received a globals dict lacking __builtins__, Python silently injected the full builtins module, exposing __import__, open, and eval. A simple payload calling os.system could yield a reverse shell. A separate path on the /guardrails/test_custom_code playground endpoint, independently reported by X41 D‑Sec, defeated a regex deny‑list by rewriting code at runtime; both paths ended in server‑side code execution.

What a full server takeover exposes

LiteLLM is deployed as an OpenAI‑compatible proxy that brokers calls to more than 100 model providers. Obsidian warned that a full chain compromise exposes the master key, the salt key used to decrypt stored credentials, and the database URL. Provider keys — for OpenAI, Anthropic, Gemini, Bedrock, Azure, and others — are within scope. Keys held in config or environment appear in plaintext; those stored in the database are encrypted but recoverable with the salt key.

Everything routed through the gateway — prompts, responses, and the data model clients send — becomes readable. In real deployments, that traffic commonly contains PII, source code, internal tickets, and pasted secrets. If the proxy functions as a Model Context Protocol (MCP) or agent gateway, OAuth tokens and tool credentials are also exposed.

Beyond data theft, the adversary can rewrite traffic. Obsidian demonstrated compromising a proxy that routed Claude Code: by using LiteLLM’s callback mechanism — an extension point that fires on every request and does not appear in the admin UI — an attacker swapped the model’s response for a forged tool call and rewrote the safety‑check context so the action appeared approved. In their demo, a developer typing the single word “hello” led to a reverse shell on the developer’s machine.

BerriAI fixes, versions to run, and recommended remediation steps

The LiteLLM maintainer, BerriAI, released the complete fix set in LiteLLM v1.83.14-stable; GitHub lists that release as published May 2. Obsidian rated the full chain CVSS 9.9. The advisory guidance is straightforward: upgrade to v1.83.14‑stable or later to close the three‑CVE chain.

Obsidian’s post‑disclosure checklist urges additional hardening: re‑verify every account holding proxy_admin and treat that role as host‑level access; review every Custom Code Guardrail; inspect callbacks defined in litellm_settings.callbacks, since those callbacks do not appear in the console and are a likely hiding place for post‑RCE persistence; and verify the integrity of deployed code, not just configuration. If exposure is suspected, rotate provider keys, database credentials, and any stored MCP tokens.

What this means for security teams, procurement leaders, and end users

  • Security teams and technologists: Upgrade immediately to v1.83.14‑stable or later, audit proxy_admin assignments, and review Custom Code Guardrails and callbacks for unauthorized changes.
  • Procurement leaders and enterprises operating gateways: Treat proxy_admin as effectively host‑level access when assessing vendor and deployment risk, and ensure deployment pipelines include integrity checks for published code and configuration.
  • End users and developers: Be aware that a compromised proxy can both read model inputs and outputs and actively forge responses. If you suspect a proxy has been exposed, expect to rotate any secrets and tokens that transit the gateway.

Obsidian framed the vulnerability chain as a disclosed flaw with a working demo rather than as evidence of exploitation in the wild, but LiteLLM’s chokepoint position has made it a recurrent target: earlier this year the project saw a backdoored PyPI release in March and a critical SQL injection exploited within 36 hours of disclosure in April. The chain is, in Obsidian’s words, a cascade of misplaced trust — the route gate trusted caller input, the handlers trusted the gate, and nobody checked. The immediate, practical remedy is simple and urgent: upgrade, audit, and rotate.

Original story