LiteLLM and your DORA register

LiteLLM and your DORA register

LiteLLM was compromised twice in 2026. The first time was in March; the archive stolen in that incident — 153 GB, analysed by Hudson Rock in August — was linked to roughly 2,500 corporate domains. The second time, on 21 October, is the more instructive one, because of where the attacker found the credential that started it.

The credential was sitting in the vendor's own logs

LiteLLM ran an internal deployment of its own product, and that deployment was reachable from the public internet. During the investigation the company found an unexpected, innocuously named user account in it. How the attacker got in has not been confirmed; LiteLLM says it suspects a recently patched vulnerability.

What the attacker found inside was worth more than the deployment: GitHub CLI OAuth tokens belonging to three of the company's own engineers, sitting in the gateway's logs. LiteLLM's explanation of how they got there is worth reading twice. In certain situations Claude Code embeds a user's GitHub CLI OAuth token into a response body — and where a gateway logs response bodies, the token is logged along with everything else. An AI gateway doing exactly what an AI gateway does had been recording credentials in plain view.

Three tokens, three jobs. One account was used to change the release pipeline and trigger a release, a second to approve it, and a third to delete the workflow records afterwards, which is why the forensic picture is thinner than it should be. The build recorded its source repository as Berri-AI/litellm — one hyphen away from the real BerriAI/litellm.

The poisoned release, version 1.107.0, was live on PyPI from 11:39 to 13:23 UTC on 21 October. The Docker tags v1.107.0, latest, main-latest and main-stable served the bad image from 11:46 to 14:20 UTC. The last safe version is 1.106.2. Customers on LiteLLM's private enterprise registry were not affected.

What shipped, and how quickly it was used

The malicious code was placed in Python startup files — a .pth file that runs whenever a Python interpreter starts in that environment, whether or not anything ever imports LiteLLM. It collected credentials for AWS, Azure, Google Cloud, Kubernetes and Docker, plus Git credentials, SSH and GPG keys, saved browser logins and cookies, browsing and shell history, the authentication files belonging to Codex, Claude, Gemini and Cursor, and whatever it could read out of a LiteLLM proxy's own database. The collected data was encrypted and sent to a "healthcheck" address on the litellm[.]dev domain. A second component polled a file on GitHub for a domain from which to download and run further Python code; when Socket checked that file on 21 October it was empty.

Wiz observed the stolen keys in use roughly four and a half hours after the data left victim systems: AWS credentials taken from CI runners and Kubernetes nodes, tested for access to models on Amazon Bedrock. Socket puts LiteLLM's weekly download count at about 23 million.

A component you never signed a contract for

Most banks have never heard of LiteLLM and will never contract with it directly. It is the kind of thing that sits a layer down: an AI gateway or proxy that a chatbot vendor, a fraud-scoring tool, or an internal "ask your data" feature routes model calls through, because writing that routing layer from scratch is wasted effort when an open-source one already exists.

That is exactly the layer a DORA register of information is supposed to reach, and routinely does not. Article 28(3) of Regulation (EU) 2022/2554 requires every contractual arrangement for the use of ICT services to be recorded, and the templates in Commission Implementing Regulation (EU) 2024/2956 cover the sub-contracting chain beneath any arrangement supporting a critical or important function — template B_05.02 exists specifically to describe subcontractors and their rank in that chain. In practice, that chain is documented down to the named sub-processor — "this vendor uses this cloud provider in this country" — and stops there. It rarely asks which open-source AI components sit underneath the vendor's product, who maintains them, or how that project handles its own credentials.

What a register entry should be able to say

For an AI-related arrangement, a register that only names the vendor is answering the wrong question. The entries worth having on file include, at minimum: the specific AI component or library in use, not just the vendor's product name; whether it is pinned to an exact, verified version — by digest, ideally — or tracks a floating tag such as latest that updates itself; how the vendor's own release process enforces separation of duties, and whether that separation survives one attacker holding three maintainer accounts; what the vendor's AI gateway or proxy logs, specifically whether request and response bodies are recorded and who can read them; what credential rotation cadence applies to the vendor's build and deployment infrastructure, not only to your own; and a notification contact specific to that component, because "contact our account manager" is not the same as "contact whoever patches the AI gateway."

None of this is exotic. It is the discipline the register already expects for cloud sub-processors, applied one layer further down, to the open-source and AI tooling those sub-processors themselves depend on. A vendor that cannot answer these questions today is giving you useful information: it means nobody has asked them internally either.

The logging question deserves particular attention after this incident, because it is the one that generalises. Any gateway that sits in the path of model traffic is, by design, in the path of whatever that traffic carries — API keys pasted into prompts, tokens embedded in tool responses, customer data in both directions. Logging is not optional for an operational system, but a register entry that records "full response bodies retained, 90 days, readable by the vendor's support team" is a materially different risk line from one that records "metadata only."

Ask it as a question, not a checkbox

The most direct way to get this into a register is to ask it of every AI-related provider at renewal, rather than waiting for a supervisor to ask it of you: which AI gateway, orchestration layer or inference library does your product depend on, how is its version pinned, what does it log, and what is your incident-notification path if that specific dependency is compromised. A vendor with a crisp answer is a lower-risk line in the register. One that has to go and find out is a sub-contracting gap you just closed before it became an incident report.

The same inventory does work under NIS 2, where supply-chain security obligations for essential and important entities cover the same ground from a different angle. Our audit, risk and compliance practice and the NIS 2 and DORA readiness checklist cover the documentation side; where the question is whether an AI-dependent system holds up under attack, that is what our LLM and AI pentest work tests; and the credential-hygiene and release-pipeline habits above are what security for developers training is built to instil before a supplier ever gets near a production key.


Sources: Help Net Security — LiteLLM hit by second supply chain attack this year, Wiz — LiteLLM compromised, steals credentials, Socket — LiteLLM PyPI package and Docker images compromised, Datadog Security Labs — LiteLLM supply chain compromise, Regulation (EU) 2022/2554 (DORA), Article 28, Commission Implementing Regulation (EU) 2024/2956. LiteLLM describes the incident as contained with the investigation still open; the route into its internal deployment is explicitly unconfirmed, and the attacker's use of stolen AWS keys is Wiz's observation rather than a vendor statement.

This article is general information, not legal or regulatory advice.

← Back to blog