LiteLLM 1.107.0 Was Backdoored: Who Is Affected and What to Rotate
TL;DR - On October 21, 2026, an attacker used LiteLLM’s own release pipeline to publish
litellm==1.107.0with credential-stealing malware to PyPI and Docker, according to LiteLLM’s incident post. - The bad release was live for about two hours: PyPI 11:39 to 13:23 UTC, Docker Hub 11:46 to 14:20 UTC, GHCR 11:46 to about 13:51 UTC. The Dockerlatest,main-latestandmain-stabletags pointed at the bad image too. - LiteLLM says all previous versions are safe and recommends pinning 1.106.2. Customers on its private enterprise registry were not affected. - If you ran it, do not start Python in that environment to check; the malware runs on every Python start. Remove the files, rebuild, then rotate every credential the host could reach. - If you pin LiteLLM to an older version and did not pull the floating Docker tags that day, you were not exposed to this release.This week’s triage: all of this week’s critical issues, ranked by what to patch first: Critical vulnerabilities, October 17 to 24, 2026
What happened#
LiteLLM is an open-source library and proxy that lets applications call many AI model providers through one interface, so it often sits next to a lot of API keys. LiteLLM’s maintainer, BerriAI, says its release pipeline was compromised early on October 21 and that version 1.107.0 contained “compiled malware which steals credentials and loads remote-code execution tools.” The official 1.107.0 source tag on GitHub does not contain the malicious files; they were added in a build made from a lookalike repository, Berri-AI/litellm, instead of the real BerriAI/litellm.
LiteLLM’s attack-chain write-up, published October 23, is the company’s canonical account and replaces its earlier status updates where they differ. In short:
- A master key for an internal LiteLLM agent platform was committed to a public repository on May 27, 2026. It was overwritten in git history but never revoked.
- On October 10, the attacker used that key to call the platform’s API, which returned a GitHub CLI token belonging to one of the two GitHub organization owners.
- With that token, the attacker pushed throwaway branches whose CI workflows sent repository secrets, including two maintainers’ GitHub tokens, to an outside endpoint, then deleted the runs.
- On October 21, the attacker changed the private release repository so the release workflow would build from the lookalike repository, used a second maintainer’s stolen token to approve the production release, and used a third to delete the workflow logs.
- LiteLLM says it noticed shortly before 13:00 UTC, froze PyPI releases by 13:23 UTC and removed the Docker images by 14:20 UTC.
LiteLLM also says a release-approval restriction had been relaxed earlier that week so that any two engineers could trigger and approve a release.
Are you affected?#
LiteLLM’s incident post says you should assume compromise if any of these apply:
| Situation | Window (October 21, 2026, UTC) |
|---|---|
You installed litellm==1.107.0 from PyPI, or an unpinned pip install litellm resolved to it |
11:39:51 to 13:23 |
You pulled or started a Docker Hub image tagged v1.107.0, latest, main-latest or main-stable |
11:46:56 to 14:20 |
You pulled the same tags of ghcr.io/berriai/litellm, litellm-database or litellm-non_root |
11:46:56 to about 13:51 |
Two less obvious routes to check:
- Indirect installs. Another package or tool that depends on LiteLLM with a loose version range could have pulled 1.107.0 during the window. Check lockfiles and build logs, not just your own requirements file.
- Caches and images built that day. A CI cache, wheel cache or container image built during the window can keep serving 1.107.0 after PyPI removed it.
You are not affected by this release if every install pins LiteLLM to an earlier version and no container pulled the floating tags in the window. Customers on LiteLLM’s private enterprise registry were not affected, per the company.
What the malware does#
According to LiteLLM and to analysis by Socket and StepSecurity:
- It runs on every Python start. A
cook.pthfile in site-packages loads the payload whenever Python starts in that environment, even if nothing imports LiteLLM. - It collects credentials. Researchers list cloud and Kubernetes credentials, SSH and GPG keys, Git, npm and PyPI tokens,
.envfiles, environment variables, browser data and configuration files for AI coding tools. On LiteLLM proxy deployments withDATABASE_URLset, it also reads the provider credentials stored in the proxy database. - It installs a loader. A
sitecustomize.pyfile starts a background process that periodically checks an attacker-controlled location for more Python code to download and run.
Socket and StepSecurity both report that stolen data was sent to litellm.dev, a domain that is not LiteLLM’s. LiteLLM’s own post does not list that domain.
What is confirmed and what is reported#
| Claim | Source | Status |
|---|---|---|
| 1.107.0 on PyPI and Docker contained credential-stealing malware | LiteLLM | Confirmed |
| Exposure windows and affected Docker tags in the table above | LiteLLM | Confirmed |
| All earlier versions are safe; pin 1.106.2 | LiteLLM | Confirmed (Socket notes it has not certified every earlier artifact) |
| Attack began with a master key exposed in a public repository in May | LiteLLM attack chain | Confirmed |
| Enterprise private-registry customers not affected | LiteLLM | Confirmed |
Stolen data sent to litellm.dev |
Socket, StepSecurity | Reported |
What defenders should do now#
LiteLLM’s cleanup steps, in its order:
- Do not start with
pip installor any Python command in an affected environment. Starting Python re-runs the payload. Inspect from outside it. - Delete the payload files from every affected site-packages directory:
cook.pth,cook.py,sitecustomize.py, and the matching__pycache__/cook*.pycandsitecustomize*.pycfiles. - Kill the background loader, the detached Python process holding
/tmp/remote_code_loader.lock. - Rebuild virtual environments and images from scratch, pinned to
litellm==1.106.2or another version published before the incident. LiteLLM prefers a rebuild to cleaning in place. - Assume the theft succeeded if 1.107.0 ran on a host with outbound internet access. LiteLLM says a missing marker file proves nothing.
- Rotate everything the host could reach, from a clean machine: cloud instance or task roles, every provider API key stored in the LiteLLM proxy database, the proxy master and virtual keys, the
DATABASE_URLpassword, and any secret in the host’s environment. Researchers add SSH and GPG keys, Git, npm and PyPI tokens, browser sessions and AI tool tokens. - Check cloud logs. LiteLLM suggests looking in AWS CloudTrail for
GetCallerIdentitycalls from the instance role around the install time, and for use of that role’s credentials from outside your infrastructure.
To look for the files without starting Python in the affected environment, run these from a normal shell. They only list files and lockfile entries:
# Payload files and the 1.107.0 install marker (site-packages or Debian/Ubuntu dist-packages)
find / -path '*-packages*' \( -name 'cook.pth' -o -name 'cook.py' -o -name 'litellm-1.107.0.dist-info' \) 2>/dev/null
# Loader lock file
ls -l /tmp/remote_code_loader.lock 2>/dev/null
# Pinned to 1.107.0 in requirements-style files
grep -rn "litellm.*1\.107\.0" --include='*.txt' --include='*.toml' . 2>/dev/null
# uv.lock and poetry.lock put the name and version on separate lines
grep -rn -A1 'name = "litellm"' --include='*.lock' . 2>/dev/null | grep '1\.107\.0'
Indicators from LiteLLM’s post:
- Docker Hub image digest:
sha256:1bbcb1443bc962e45f5aad53fe3d2c30600e0379715fb6c664cdd3ac126c339e - Lookalike source repository:
Berri-AI/litellm - Unauthorized workflow commit:
9cf97e935aeaf791b9c8db224a2bb3ee156134ce - Attacker-controlled source commit:
20535d8fa11f786a6c24df7488a0e449ed5f09ad
LiteLLM lists separate GHCR digests for litellm-database and litellm-non_root; use its post for those and for any indicators it adds later.
For the longer term: pin dependencies to exact versions with hashes, avoid floating Docker tags such as latest in production, and keep the secrets an AI gateway can read to the minimum it needs. This incident started with a key that was overwritten in git history but never revoked; revoking a leaked key is the fix, deleting the commit is not.
Related reading: What is a software supply chain attack? and AI supply chain security
This advisory is informational and is updated as vendors publish details. Confirm versions and actions against the vendor’s own guidance for your environment.
Sources
- Primary notice: LiteLLM, Contained: Oct 21, 2026 LiteLLM release v1.107.0 compromised (October 21, 2026)
- Primary notice: LiteLLM, The attack chain behind the v1.107.0 LiteLLM release (October 23, 2026)
- Research: Upwind report, GitHub issue #47826 (October 21, 2026)
- Research: Socket
- Research: StepSecurity