The auth path is doing more than checking a token
LiteLLM acts as an LLM gateway and API proxy, so the auth layer is part gatekeeper, part traffic cop. A Bearer token is hashed and checked on each request, but that check feeds into routing and identity decisions that affect the rest of the request flow. If the lookup path is fragile, the failure can spread past simple rejection.
Where routing, billing, and proxy identity meet
That boundary is awkward because auth is tied to database-backed key state. A request can touch models, user lists, and key lists, which means the proxy is not just deciding access at the edge. It is also reading state that influences how the request gets handled. Once that state lookup becomes unreliable, the proxy is only one bad branch away from behaving as if a key belongs to someone else.
The weak assumption: a failed lookup is just a failed lookup
That assumption breaks fast when the code treats lookup failure as a recoverable event. In the LiteLLM paths documented during Pwn2Own Berlin 2026 preparation, one version wrapped the auth builder in a broad exception handler. If the database was unavailable and the proxy was configured to allow requests in that state, the fallback returned an auth object mapped to the proxy admin identity. That is not a small failure mode. It is a different trust decision.
The chains that turn lookup failures into control
The attack chains worked because the proxy let an auth failure become a state change. One path pushed Prisma into connection trouble. Another relied on exception handling that handed back an admin identity instead of stopping the request. Each step was dull on its own. Chained together, they were not.
Uncached fake Bearer tokens and Prisma pool exhaustion
A fake token still costs something if the proxy looks it up properly. In the affected flow, unique fake Bearer tokens were not negatively cached, so each one forced a fresh Prisma lookup. With no useful throttling at the auth endpoint, repeated misses could drive the Prisma connection pool into exhaustion. The pool default was 10 connections with a 60 second timeout, which is not much grace when every miss keeps asking the database the same pointless question.
That matters because the lookup happens before the proxy can separate nonsense from a real request. If the key is always new, the cache never helps. If the endpoint is unthrottled, the attacker gets to spend database connections faster than the proxy can recover them. The failure is not dramatic. It is just a queue that never drains.
Exception handling that falls back to proxy-admin identity
The other weak point was more direct. The auth builder caught exceptions broadly, and the database-unavailable handler could return a UserAPIKeyAuth object with the proxy admin identity. The fallback set a fixed key name and token tied to the failed connection path, then assigned the default user ID to the proxy admin name. If that path is reachable, the proxy stops treating the request as unauthenticated and starts treating it as admin.
That is the sort of boundary mistake that makes a routing proxy dangerous. The control flow does not fail closed. It keeps moving, just with the wrong identity attached. Once the auth layer hands over proxy-admin context, the rest of the request no longer needs a real Bearer token to feel legitimate.
Tightening the boundary without breaking the proxy
The safest control is boring: fail closed when the auth backend is unavailable. A proxy that returns admin identity on database error has already lost the boundary, so that fallback needs to stop. If the service must keep serving some requests during database trouble, the fallback identity has to be unprivileged and tightly scoped.
Negative caching for invalid keys also matters. A fabricated Bearer token should not force a fresh database lookup every time. Without that cache, the proxy turns repeated garbage into load on the auth store. Rate limiting on auth endpoints is the obvious companion control, because unthrottled pre-auth requests are a neat way to turn lookup logic into a connection pool problem.
The boundary should also treat auth failures, database failures, and identity assignment as separate cases. Mixing them into one exception path is what created the admin fallback in the first place. Keep lookup failure as lookup failure, not a quiet promotion to proxy-admin.



