LiteLLM's JWT authentication contains an identity-matching shortcut that can turn an ordinary, validly signed login token into another person's account — including a proxy_admin holding every upstream LLM provider key the organisation has configured. The flaw, CVE-2026-93355, was disclosed by OX Security after what it describes as roughly 120 days without a vendor response. As of 4 October, LiteLLM has shipped no fix. Two other LiteLLM CVEs added to the GitHub Advisory Database in late September, a semantic-cache tenant isolation bypass (CVE-2026-89032) and a credential-exfiltrating SSRF (CVE-2026-84377), do have patches. Any organisation that uses LiteLLM's JWT/SSO authentication should change its identity provider configuration now rather than wait for a release.
CVE-2026-93355: how an email claim becomes an admin session
According to OX Security researchers Nir Zadok and Moshe Siman Tov Bustan, LiteLLM resolves JWT-bearing requests in two stages. It first tries a direct match on user_id or sso_user_id. When that misses — which is the normal case the first time a given token subject is seen — get_user_object calls a fallback, _get_fuzzy_user_object, which looks the user up by the email claim in the token.
OX highlights two problems in that fallback:
- The email is trusted outright. The lookup is a plain case-insensitive equality match, and
email_verified"does not appear anywhere inhandle_jwt.py." The only nearby control, an email-domain allowlist (user_allowed_email_domain), is off by default. - A match rewrites the victim's identity. On a hit, the function schedules a background task (
asyncio.create_task, not awaited) that overwrites the matched account'ssso_user_idwith the attacker's token subject. From then on, the attacker's token matches directly on the fast path, with no fallback needed.
We checked the current source. In litellm/proxy/auth/auth_checks.py on the project's main branch on 4 October, _get_fuzzy_user_object still performs the insensitive email lookup and the background sso_user_id update, with no email_verified check.
The attack scenario OX demonstrated
- A
proxy_adminaccount exists with an email such asadmin@target.com. OX notes this describes "any existing SSO user who has ever logged in." - The attacker, holding any account at an IdP the proxy trusts, obtains a validly signed JWT for their own subject with
emailset to the victim's address andemail_verified=false. OX says several common IdP and self-service signup flows issue such tokens without any misconfiguration. - The attacker sends an ordinary request, for example
POST /chat/completions. The subject lookup misses, the email fallback matches the victim, and the request runs with fullproxy_admincontext. - In the background the victim's
sso_user_idis rebound to the attacker. The same token then reaches admin-only endpoints such askey/listanduser/list, along with every provisioned upstream API key behind the proxy.
OX built a working proof of concept, confirmed both the takeover and the persistent rebind, and has not published exploit code. No in-the-wild exploitation has been reported, and the CVE is not in CISA's KEV catalog.
Scoring and disclosure timeline
The sources disagree on the details. OX scores the flaw CVSS 3.1 8.8 (AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H) and classes it as CWE-290 (Authentication Bypass by Spoofing). The CVE record from CNA VulnCheck uses CVSS 4.0 7.6 (AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:N) and CWE-1390 (Weak Authentication). OX confirmed the flaw "through 1.100.1"; the VulnCheck record lists LiteLLM up to 1.102.1 as affected.
| Date | Event (per OX Security and the CVE record) |
|---|---|
| 18 May 2026 | Vulnerability reported to LiteLLM |
| 27 July 2026 | OX follow-up requesting status; no response |
| 14 September 2026 | OX proceeds to public disclosure after ~120 days without a vendor response |
| 28 September 2026 | CVE-2026-93355 published to NVD and the GitHub Advisory Database |
| 29 September 2026 | OX Security research post published |
| 4 October 2026 | No fixed release; the email fallback is unchanged on main |
CVE-2026-89032: semantic cache returns other tenants' answers and tool calls
CVE-2026-89032 (CWE-863, CVSS 4.0 8.7) is a tenant isolation bypass in LiteLLM's semantic cache. The CVE description attributes it to a metadata key mismatch between _get_semantic_cache_tenant_scope() and _get_metadata_variable_name(). A holder of any valid virtual key could submit semantically similar prompts on affected routes such as /v1/responses and /bedrock/* and get back other tenants' cached responses, which could contain personal, financial or source-code data. In agentic deployments it is worse: cached function_call or tool_calls payloads could be returned to a different principal, causing agentic front-ends to "auto-execute attacker-supplied tool calls under victim credentials." The fix landed in PR #39590 and shipped in 1.101.0-rc.1.
CVE-2026-84377: proxy users could redirect calls and take the operator's keys
CVE-2026-84377 (CWE-918, CVSS 3.1 6.5) is covered in LiteLLM's own advisory GHSA-3cv6-jpf6-8222. Any authenticated proxy user could redirect an outbound provider call to a destination they controlled. The proxy would send its configured provider credentials along with it. The request-body validation was a denylist that missed some sensitive parameters and did not inspect values nested inside other fields. The result was credential exfiltration plus server-side request forgery against internal services reachable from the proxy. This is a separate bug from the configuration-injection SSRF we covered as CVE-2026-59823.
Affected and fixed versions
| CVE | Issue | Affected | Fixed | Score |
|---|---|---|---|---|
| CVE-2026-93355 | JWT email fallback account takeover | Through 1.102.1 (CVE record); confirmed through 1.100.1 (OX) | No fix available | CVSS 4.0 7.6 / OX CVSS 3.1 8.8 |
| CVE-2026-89032 | Semantic cache tenant isolation bypass | Before 1.101.0-rc.1 | 1.101.0-rc.1 | CVSS 4.0 8.7 |
| CVE-2026-84377 | Credential exfiltration / SSRF via request parameters | < 1.88.6; 1.89.0–<1.89.7; 1.90.0–<1.90.7; 1.91.0–<1.91.5; 1.92.0–<1.92.2; 1.93.0–<1.93.2; 1.94.0–<1.94.3; 1.95.0–<1.95.1; 1.96.0–<1.96.2 | 1.88.6, 1.89.7, 1.90.7, 1.91.5, 1.92.2, 1.93.2, 1.94.3, 1.95.1, 1.96.2 | CVSS 3.1 6.5 |
LiteLLM has a history of serious proxy flaws: see our earlier coverage of the pre-authentication SQL injection CVE-2026-42208. Every one of them comes down to the same point. The proxy holds the organisation's real provider keys, so any identity or request-validation bug in it exposes all of them.
Defensive playbook
- Enforce verified email at the trust boundary. OX calls this the single control that directly blocks the attack. Make sure the IdP application LiteLLM trusts only issues tokens with
email_verified: true, or strip or rewrite theemailclaim upstream (at a reverse proxy or in IdP claim mapping) for any token that lacks it. Disable self-service signup on that IdP app. - Pin identity to a stable subject. Configure
user_id_jwt_fieldso every trusted issuer supplies a stable, unique subject from the first login, keeping requests away from the email fallback. Adduser_allowed_email_domainas defence in depth; OX notes it stops foreign-domain spoofing but not a same-domain colleague's address. - Do not pre-provision privileged accounts by email. Create
proxy_adminaccounts only once their stable subject identity is known and can be bound directly, so no email-only admin account is waiting to be claimed. - Look for rebinds that already happened. As a starting point, list admin users and their SSO subjects, then compare them against your IdP's subject IDs for those people:
An-- LiteLLM Postgres (Prisma) schema SELECT user_id, user_email, sso_user_id, user_role, updated_at FROM "LiteLLM_UserTable" WHERE user_role = 'proxy_admin' ORDER BY updated_at DESC;sso_user_idthat does not belong to the account owner's IdP identity is a takeover indicator. Rotate that account's keys and every upstream provider key the proxy holds. - Patch the two fixed CVEs. Upgrade to a release containing the fixes for CVE-2026-89032 (1.101.0-rc.1 or later) and CVE-2026-84377. Until then, set
general_settings.allow_client_side_credentials: false, disable semantic caching on multi-tenant routes, and blockapi_base,base_url,model_list,fallbacksand provider credential fields at a gateway.pip show litellm | grep -i '^version' pip install --upgrade litellm - Keep the proxy off the internet. OX recommends removing public inbound rules on LiteLLM ports (it cites 4000 and 8000) and allowing only internal CIDRs or VPN ranges. It also notes that insiders can still exploit CVE-2026-93355 until a fix ships.



