LiteLLM exploit chains at the auth boundary

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.

Related posts

OCI image trust for Linux host observability

Inspektor Gadget OCI images make deployment easy, but they also move trust to places people rarely examine. I would rather be awkward about signatures, TLS and build inputs now than discover later...

Object.prototype pollution in Acrobat Reader DC parsing

Adobe Acrobat PDF parsing is one of those areas where a small trust mistake becomes something much nastier. I spent time tracing how polluted prototypes slip into privileged JavaScript, and the path...

LiteLLM exploit chains at the auth boundary

LiteLLM exploit chains only work because the auth boundary is doing too much, and failing badly when the database wobbles. I trust a proxy less when a bad lookup can quietly turn into proxy-admin...