Off Guard: Breaking LiteLLM from authentication bypass to cloud compromise
Off Guard: Breaking LiteLLM from authentication bypass to cloud compromise
How default keys, unauthenticated MCP sessions, and custom code guardrails expose cloud AI infrastructure to root-level remote code execution and IAM theft.
Nearly 1 in 10 publicly accessible LiteLLM instances accept a default master key or require no authentication at all. We found this while scanning roughly 3,000 internet-facing deployments of the most popular open-source LLM gateway. The usual concern with that kind of exposure is LLMjacking -someone using the credentials to run API calls on your bill - however, we wanted to check whether an attacker could do worse than that: could they achieve code execution on the host? Furthermore, could they exploit this to compromise the wider environment?
We decided to use Claude Code to work through LiteLLM's codebase, looking for features that accept user-controlled input and pass it to an execution context. We found multiple issues, as detailed below.
Key findings:
MCP authentication bypass via the MCP endpoint (CVE-2026-59822) - an arbitrary Bearer token can create a valid session; confirmed as exploitable across hundreds of Internet-facing instances.
9.6% of 3,074 public instances (at the time of this research) accepted the default master key (sk-1234) or required no authentication at all. In these cases, the RCE is effectively pre-auth.
Unauthenticated access as admin by default (no CVE assigned; fixed alongside CVE-2026-59821) - when no authentication is configured, all users are granted PROXY_ADMIN access.
Post-auth cloud credential theft vector via the pass-through endpoint feature, as it lacks URL validation.
This isn’t considered a vulnerability and therefore wasn’t fixed or assigned a CVE, meaning the technique remains abusable in post-auth scenarios. However, similarly to the above, when chained with a default master key or missing authentication, this is effectively pre-auth.
All vulnerabilities have since been responsibly disclosed to LiteLLM and have patches available. CVE-2026-59822 has been added to CISA's Known Exploited Vulnerabilities catalog, and we observed it being exploited in the wild via our honeypot infrastructure. This research was previously presented at DEF CON 34.
Background: What is LiteLLM?
LiteLLM is an open-source AI gateway that provides a unified OpenAI-compatible API for over 100 LLM providers, including OpenAI, Anthropic, AWS Bedrock, Azure, and Google Vertex AI. Organizations route their LLM traffic through it so they can centrally manage their API keys, enforce budgets, apply guardrails, monitor usage, etc.
LiteLLM is one of the most popular open-source AI gateways, present in approximately one-third of cloud environments according to Wiz data. LiteLLM can hold API keys for every configured LLM provider, process every prompt and response that flows through it, and connect to external tools via MCP. A compromised LiteLLM instance means compromised AI infrastructure, and, as we'll show, often the cloud environment it runs in.
The conventional risk model for this is LLMjacking: an attacker makes API calls on the organization's behalf, runs up costs, and exfiltrates whatever provider keys are configured. While this is indeed a proven real-world risk, LiteLLM isn't just a credential store. It executes server-side Python on every inference request, can proxy requests to arbitrary internal URLs, and connects to internal tools and systems via MCP. Therefore, we wanted to know what an attacker could actually do with a compromised instance beyond just API abuse.
Searching for Attack Paths
Using Claude Code, we went through guardrails, pass-through endpoints, model configuration, hook systems, and the MCP layer. Three features had obvious attack surface:
MCP authentication handler (user_api_key_auth_mcp.py): a separate auth path for the Model Context Protocol endpoint
Custom code guardrails (guardrail_endpoints.py): administrators submit Python code that the server passes to exec(compile(...))
Pass-through endpoints (pass_through_endpoints.py): proxy routes that forward requests to arbitrary URLs with no validation
MCP Authentication Bypass (CVE-2026-59822)
LiteLLM supports MCP (Model Context Protocol), a standard for connecting AI models to external tools and data sources. The MCP endpoint has its own authentication handler, separate from the main LiteLLM auth. It was designed to support a dual authentication model: LiteLLM API keys for direct users, and OAuth2 token passthrough for users authenticating via upstream providers like GitHub or Atlassian. The idea is simple - if a Bearer token isn't a valid LiteLLM key, pass it through to the upstream MCP server as an OAuth2 token.
The problem is in the fallback logic. When a token fails LiteLLM validation, the handler doesn't distinguish between "this is a legitimate OAuth2 token meant for an upstream provider" and "this is complete garbage." It catches the 401 error and silently returns an empty auth object - granting access as if the request were authenticated:
elif oauth2_headers: try: validated_user_api_key_auth = await user_api_key_auth( api_key=litellm_api_key, request=request ) except HTTPException as e: if e.status_code in (401, 403): validated_user_api_key_auth = UserAPIKeyAuth() # bypass else: raise
This branch triggers for any request with an Authorization header - which is every normal Bearer token request. Any garbage token fails validation with a 401, and the handler proceeds as if nothing happened. The exploit is one request, as demonstrated below. Note that Authorization: Bearer a , containing a single character, is enough to establish a fully authenticated MCP session:
Once inside, an attacker has access to the full MCP protocol. Not just read operations, but rather the ability to execute tools with arbitrary arguments. If an MCP server exposes a database query tool, the attacker can run queries. Similarly, if it connects to GitHub, the attacker can read repositories and create issues. If it has access to a file system, the attacker can read and write files.
Which MCP servers an attacker can reach depends on how the organization has configured them. LiteLLM supports an allow_all_keys flag that makes an MCP server available to every user, including the empty credential created by the auth bypass. LiteLLM's documentation recommends this setting for "internal knowledge bases, calendar integrations, or other low-risk utilities where every team should be able to connect without requesting access."
Furthermore, organizations deploying LiteLLM internally are more likely to connect MCP servers to sensitive systems: Jira for project management, Slack for communications, internal databases for business data, and CI/CD pipelines for deployment automation. These environments assume network-level security and often configure broader tool access. This authentication bypass vulnerability gives an attacker direct access to these connected sensitive systems.
Post-Auth Root-Level Code Execution via Custom Code Guardrails (CVE-2026-59821)
LiteLLM's guardrails feature lets administrators define policies that run on every LLM request, including blocking sensitive prompts, filtering outputs, and enforcing compliance rules. Custom Code Guardrails extends this: administrators write Python-like code that the server executes before or after every inference call.
The intended design has a sandbox. The Web UI's "Run Test" button validates code against a forbidden patterns list and strips __builtins__ before execution, blocking import, os, subprocess, and similar. But the registration endpoint (POST /guardrails) applies neither protection.
When a guardrail is created, the server calls _compile_custom_code() in custom_code_guardrail.py:
Two things are missing from this path. First, the forbidden patterns check - which blocks import, exec(), eval(), os, subprocess, and dangerous attributes - only runs in the test endpoint. Second, the test endpoint explicitly sets exec_globals["__builtins__"] = {} before execution, while the registration endpoint does not. Python repopulates __builtins__ automatically when it's absent, so submitted code gets the full standard library.
The code executes immediately when the guardrail is registered, since the import os and os.popen('id') run during initialization, before any LLM request. The result is stored in _cmd. An attacker can send any chat completion to invoke the guardrail and see the output returned as the block reason:
Guardrail endpoints now require PROXY_ADMIN. The CRUD endpoints explicitly check for admin role instead of accepting any valid key.
Sandbox properly enforced on registration. The exec() path now strips builtins and runs the forbidden-patterns check before compilation, matching the test endpoint's behavior.
In other words, custom code guardrails always run within a sandbox, and the feature itself is now fully admin-gated, whether or not authentication is configured. The fix blocks the path from a regular API key, or no key at all, to code execution. That means an attacker trying to abuse this feature in newer versions would require admin-level access to do so, and would only be able to execute code within the sandbox.
—
Note that the abovementioned MCP auth bypass vulnerability only allows MCP server access, and does not allow exploitation of this post-auth RCE vulnerability.
So considering that this vulnerability is only exploitable by an authenticated admin user in the first place, the important question becomes under what conditions an attacker could bypass authentication to admin in order to exploit it, which leads us to our next two topics.
Unauthenticated Admin by Default
LiteLLM supports several authentication mechanisms: a master key (the primary method), JWT/OAuth2, and virtual API keys. The master key is the most common: it serves as both the admin credential and the toggle for authentication itself. When a master key is set, all API requests must include a valid key. When no master key is set (and no JWT/OAuth2 is configured), the proxy runs with no authentication at all and every request is accepted.
Pre-patch, this had two compounding problems:
First, when no master key was set, LiteLLM's auth handler globally assigned the PROXY_ADMIN role to every incoming request. Not just "unauthenticated access," but unauthenticated *admin* access to the entire proxy.
Second, even when authentication was enabled, neither the guardrail CRUD endpoints nor the config update endpoint (used for configuring pass-through routes) required the PROXY_ADMIN role. Both used a generic auth dependency that accepted any valid API key, so any authenticated user could reach them.
PR #22095 addressed the default role (changed from PROXY_ADMIN to INTERNAL_USER) and added PROXY_ADMIN checks to the guardrail endpoints. The config update endpoint was fixed separately in v1.83.0 (CVE-2026-35029).
Unchanged Default Master Key
Whether or not authentication is properly configured, the LiteLLM master key serves as the proxy’s admin credential. However, LiteLLM uses it not just for API authentication but also as the HS256 secret for signing session JWTs. This means that unless the user changes it from the default value (sk-1234), anyone can forge arbitrary user sessions for the entire proxy. LiteLLM's documentation uses sk-1234 as the example master key in quickstart guides, Docker Compose examples, and configuration tutorials throughout the docs, and many deployments simply never change it.
We scanned roughly 3,000 publicly exposed LiteLLM proxies in February 2026 and tested their authentication:
Total instances found: 3,074
Default key accepted: 294 (9.6%)
↳ Of which, no auth at all: 191 (6.2%)
Nearly 1 in 10 instances accepted a default master key or required no authentication at all, and this only accounts for what's visible on Shodan. A follow-up scan in August 2026 found over 85,000 instances, though the majority appear to be honeypots or test deployments. As of today, the master key is still set by default to sk-1234 when installing LiteLLM via Docker compose or pip install.
According to Wiz's data, one-third of cloud environments have a LiteLLM deployment. Many more instances sit behind corporate networks and VPNs, accessible to internal attackers, compromised workloads, or anyone with network access to the cluster.
In any instance with the default master key unchanged that also happens to be running a version vulnerable to CVE-2026-59821 (before v1.82.0), the abovementioned RCE vulnerability is directly exploitable: a single request with a default key yields root access to the container and everything it can reach within the environment. In later versions, an attacker authenticating with the default master key could only abuse custom code guardrails to execute code within a sandbox, as mentioned above.
However, even without exploiting any vulnerabilities, a default or missing master key still gives an attacker direct access to every LLM provider API key configured on the proxy. This enables LLMjacking - hijacking an organization's LLM API access to run workloads on their budget. LLMjacking attacks have historically been observed in the wild as causing hundreds of thousands of dollars in damage to affected organizations and cloud providers.
—
Looking beyond RCE and LLMjacking, our next question was: if an attacker successfully authenticates as admin, how far can they get in the larger environment?
Post-Auth Cloud Key Compromise via Pass-Through Endpoint
It turns out that even without needing to exploit the guardrails vulnerability, the master key gives access to more than most people probably expect. LiteLLM has a pass-through endpoint feature that lets admins create proxy routes that forward requests to arbitrary URLs. The target URL is never validated; there are no checks against private IP ranges, localhost, or cloud metadata endpoints. An admin can point a pass-through endpoint at the AWS metadata service and use it to exfiltrate IAM credentials:
This works against both IMDSv1 and IMDSv2. Even on instances where only IMDSv2 is available, LiteLLM's header forwarding mechanism defeats it. Any header prefixed with x-pass- is forwarded to the target with the prefix stripped, so x-pass-X-aws-ec2-metadata-token-ttl-seconds: 21600 arrives at the IMDS endpoint as X-aws-ec2-metadata-token-ttl-seconds: 21600. This renders IMDSv2 protections ineffective.
LiteLLM rightfully uses a threat model where admins are inherently trusted, so this pass-through feature is arguably working as intended and isn’t considered a vulnerability that needs to be fixed. However, it becomes a security issue when combined with default credentials or an authentication bypass vulnerability, and given the prevalence of default credentials in the wild (as described above), this threat model has often been broken.
It's also worth noting that before v1.83.0, the config update endpoint that controls pass-through routes did not require PROXY_ADMIN at all. Any authenticated user (not just admins) could configure arbitrary pass-through endpoints. This was fixed separately from the guardrail RCE and assigned CVE-2026-35029 (unrelated to our research).
AI Gateways as Cloud Attack Surface
In a typical cloud deployment, LiteLLM's service account has permissions to invoke models on Bedrock or Vertex AI, access secrets in parameter stores, and interact with other cloud services. This makes it a highly valuable target for attackers, since it opens lateral movement paths to sensitive resources across the larger environment.
In our view, these vulnerabilities in LiteLLM point to a broader challenge: in recent years AI gateways have become critical infrastructure without corresponding security controls. They hold credentials for every AI provider, execute arbitrary code, connect to internal tools via MCP, and operate with broad cloud permissions - yet the security model is often reduced to a single shared secret.
This isn't unique to LiteLLM. As organizations adopt AI gateways, model serving platforms, and agent frameworks, they're creating a new class of highly privileged infrastructure that sits between application code and cloud services. The lesson here is that these systems need to be treated as Tier-1 security assets rather than developer tools.
Remediation
If you're running LiteLLM, we recommend the following actions:
Use a strong, unique master key - not sk-1234 or other defaults
Review guardrails for unexpected entries and restart the process to clear memory
Audit pass-through endpoints and restrict container network egress
Apply least-privilege IAM roles (IRSA or equivalent)
How Can Wiz Help
Wiz customers are already protected. Wiz automatically detects LiteLLM deployments across your cloud environment and flags vulnerable versions, misconfigured authentication, and exposed management endpoints.
Wiz Vulnerability Scanner detects vulnerable LiteLLM versions in container images and running workloads.
Wiz Runtime Sensor detects anomalous code execution within LiteLLM containers, such as unexpected process spawning from the Python runtime.
Wiz ASM discovers shadow LiteLLM deployments that may have been stood up outside of your standard provisioning process.
Wiz customers can use the pre-built queries and advisory in the Wiz Threat Intel Center to search for relevant instances in their environment.
Responsible Disclosure Timeline
2026-02-18 RCE Vulnerability discovered and reported to LiteLLM maintainers
2026-02-25 RCE and sandbox escape fix released (v1.82.0)
2026-04-25 MCP authentication bypass fix released (v1.84.0)
2026-07-07 CVE-2026-59822 exploitation observed in Wiz honeypot
2026-07-08 CVE-2026-59821 (RCE) and CVE-2026-59822 (MCP auth bypass) published
Fixing security vulnerabilities in code takes seconds, while patching in production creates high operational costs and risk. Discover how empowering developers as your first line of defense eliminates exposure across every phase of your software pipeline.
Wiz honeypots uncover active campaigns targeting LiteLLM, MCP servers, and AI frameworks through RCE, blind prompt injection, and memory credential theft.
Get a personalized demo
Ready to see Wiz in action?
"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management
How it works
Once you click Generate, Ollama reads this article and crafts 5 comprehension questions. Your answers are graded against the article content — general knowledge won't be enough. Score 70+ to count toward your certificate.
Questions are cached — you'll always get the same 5 for this article.