The LiteLLM compromise of October 21, 2026 shipped a credential stealer in version 1.107.0 of the open source LLM proxy, through PyPI and the project’s official Docker images. The v1.107.0 git tag was clean. According to an analysis by the security firm Upwind, the release was built from a lookalike GitHub repository, Berri-AI/litellm, carrying attacker commits on top of that tag.
The Malicious Files Were Absent From the Tag and Present in Every Wheel
All seven LiteLLM 1.107.0 wheels on PyPI contained three extra files that pip places at the root of site-packages. Upwind researcher Lidor Machluf reported this in an issue on the official BerriAI/litellm repository at 12:06 UTC on October 21. The source tarball carried one line that is not in the tagged tree: a directive telling maturin, the Rust and Python build tool LiteLLM uses, to bundle a directory called cook into the wheel. PyPI received the upload between 11:39 and 11:40 UTC. Anyone who read the tagged source would have found nothing wrong. Aikido Security researcher Ilyas Makari reached the same conclusion, writing that the directory did not exist in the source tarball or on GitHub.
Build Provenance Named a Repository With One Extra Hyphen
The SLSA provenance that BuildKit attached to every v1.107.0 Docker image records the source as github.com/Berri-AI/litellm, with a hyphen, instead of the project’s real BerriAI/litellm. Upwind found that the same release tooling, a BerriAI/project-releaser workflow, had recorded the correct repository for version 1.106.2 at 09:15 UTC that morning and for earlier releases. Only 1.107.0 came from the lookalike. Ten attacker commits sat on top of the tag, made through GitHub’s web editor, which is why most carried GitHub’s “Verified” badge. Upwind notes that the badge only shows a commit was made on github.com. The researchers said they do not know how the build environment or the publishing credential was compromised and put that question to the maintainers.
Floating Docker Tags Delivered the Stealer to Proxy Deployments
On both GHCR and Docker Hub, the latest, main-latest and main-stable tags pointed to the infected 1.107.0 image, so any deployment pulling a floating tag after about 11:48 UTC received it. The stealer collected SSH keys, cloud and Kubernetes credentials, browser passwords, AI tool configs and the environment variables of every readable process. Where a DATABASE_URL was set, it dumped the proxy’s stored upstream provider keys. A second file started a background process that checked a GitHub file every hour for a server address to fetch and execute code from. Upwind found that file empty, so the remote stage was dormant, and Aikido later reported that GitHub took the repository down. The exfiltration domain, litellm.dev, was registered on October 13, 2026 and is not the project’s litellm.ai.
PyPI removed 1.107.0 within hours, and by 17:13 UTC the floating Docker tags no longer pointed to the infected image. TechCrunch’s Sarah Perez reported that LiteLLM confirmed on X that it had removed the malicious releases and images.
LiteLLM Compromise Remediation Starts Before Running pip
Upwind’s guidance is to delete the injected files from the shell first, because any Python start in an affected environment, pip included, runs the payload again. Users should then kill the background process, rebuild on version 1.106.2, and assume exfiltration succeeded on any host with outbound internet access. That means rotating the instance or task IAM role, every provider key stored in the proxy database, the master and virtual keys, the database password and every secret in the host’s environment.
Why This Matters for Engineering Leadership
The LiteLLM compromise defeated source review, because the code under the tag was fine. The evidence of tampering lived in build metadata: a source repository field one character off. Leaders running an AI gateway should ask three things of their platform teams this week. First, are production images pinned by digest instead of a floating tag like latest, so a poisoned release cannot arrive on the next restart? Second, does anything check that the source recorded in a package’s provenance matches the project’s real repository? Third, is the gateway’s blast radius known? A LiteLLM proxy with a database stores the upstream provider keys it routes to, and this stealer was written specifically to dump them. Upwind also asked LiteLLM to adopt PyPI Trusted Publishing with attestations, noting the project had never published them. Teams can make attestations a condition for adopting any dependency that holds credentials.
FAQ
Which LiteLLM version was compromised?
LiteLLM 1.107.0, published on October 21, 2026. All seven PyPI wheels and the matching Docker images on GHCR and Docker Hub carried the malicious files.
What did the malicious LiteLLM release do?
It installed a credential stealer that ran on every Python start and a loader that checked a GitHub file hourly for a server to fetch and execute code from. On proxies with a database, it dumped the stored upstream provider keys.
How did malicious code get into LiteLLM 1.107.0?
According to Upwind’s analysis, the release was built from a lookalike repository, Berri-AI/litellm, with attacker commits stacked on top of the clean v1.107.0 tag. How the build or publishing credential was compromised is not yet known.
Were LiteLLM Docker users affected?
Yes. The latest, main-latest and main-stable tags pointed to the infected image until they were yanked, so anyone who pulled those floating tags from about 11:48 UTC on October 21 received it.
What should LiteLLM users do now?
Remove the injected files from the shell before running any Python, rebuild on version 1.106.2, and rotate every credential the host could reach, including provider keys stored in the proxy database.
