LiteLLM 1.107.0 on PyPI and Docker was backdoored with a credential stealer and remote code loader
LiteLLM 1.107.0 on PyPI and official Docker images ran a credential stealer on every Python start; roll back to 1.106.2 and rotate all reachable secrets.
- Published
- Updated
- Fixed in
- No patch for 1.107.0, which was removed. Roll back to litellm 1.106.2, the last known safe release per Datadog, Wiz and Endor Labs. StepSecurity reports clean releases resumed on October 24 and suggests 1.106.4.
- Exploitation
- Yes, Wiz observed stolen AWS credentials validated by the attacker from about 16:20 UTC on October 21, and PyPI recorded about 49,000 downloads of the malicious version
What happened
On October 21, 2026, attackers published a malicious litellm 1.107.0 to PyPI and into LiteLLM’s official Docker images. Datadog Security Labs reports it was live for roughly two hours. Wiz says it was published at 11:39 UTC, quarantined on PyPI at 13:20 UTC, and had about 49,000 downloads. The affected container tags were v1.107.0, latest, main-latest and main-stable, removed around 13:53 UTC. This is the second LiteLLM supply chain compromise of 2026. Datadog says the earlier one, affecting 1.82.7 and 1.82.8, was linked to TeamPCP, and no connection between the two has been established.
How the malware works. The wheels add three files to site-packages: cook.pth, cook.py and sitecustomize.py. Python runs these on every interpreter start, so the payload fires even if LiteLLM is never imported (Endor Labs). The delivery is one line, data = “cook”, added to the maturin build configuration. The official v1.107.0 tag does not contain it, so reviewing the tagged source misses the attack (Endor Labs).
- Credential stealer (cook.py). It collects cloud, developer, AI-tool and browser secrets, plus the provider keys stored in the LiteLLM proxy database. It encrypts them and posts them to the lookalike domain www.litellm[.]dev/healthcheck (Datadog Security Labs, Aikido).
- Remote code loader (sitecustomize.py). Every hour it reads a domain from a GitHub dead drop (letters9813/pythonclient-test, since removed) and runs Python fetched from http://{domain}/codepy. Wiz says it only runs on Linux and macOS. Datadog and Wiz report the file only ever held test values, so no second stage was observed in the wild. Microsoft says remote retrieval and execution were not confirmed (Microsoft Security Blog).
How the release was hijacked. The build ran through LiteLLM’s real release workflow against a lookalike fork, Berri-AI/litellm (one hyphen different from BerriAI/litellm). The provenance therefore looked legitimate while recording the malicious fork as the source (Datadog Security Labs).
The root cause account changed over time:
- Early statements relayed by Datadog, Wiz and Microsoft described stolen GitHub CLI OAuth tokens from three engineers’ accounts. Wiz also relayed a theory about exposure through an internal LiteLLM deployment.
- StepSecurity reports that BerriAI later said those early theories were wrong. It says a leaked key that was never revoked gave the attacker a GitHub organization owner’s token 11 days before the release.
- The StepSecurity excerpt available to us was truncated, so treat the full chain as not confirmed here.
Post-exploitation. Wiz observed the attacker validating AWS instance role credentials harvested from CI runners and Kubernetes nodes between 16:20 and 17:01 UTC. The calls were sts:GetCallerIdentity followed by Bedrock model listing, which Wiz describes as consistent with LLMjacking. A few environments also saw IAM enumeration.
Am I affected?
You are affected if any of these apply:
- You installed litellm==1.107.0 from PyPI. All seven compiled wheels (macOS, manylinux, musllinux, Windows) carry the payload. Datadog, Wiz, StepSecurity and Endor Labs all list 1.106.2 as the last safe release.
- You pulled or ran ghcr.io/berriai/litellm, litellm-database, litellm-non_root or docker.io/litellm/litellm at v1.107.0, or latest, main-latest or main-stable while those tags pointed to it.
- Your dependency range was open-ended (litellm>=) and a fresh install or lockfile refresh ran on October 21. StepSecurity notes this would have picked up 1.107.0.
Exposure windows differ by source, so use the wider one:
- Aikido gives 11:39 to 12:47 UTC for pip installs and 11:46 to 14:20 UTC for images.
- Datadog and Wiz give PyPI quarantine at 13:20 UTC.
- StepSecurity says GHCR tags were gone by 13:51 UTC and Docker Hub tags were repointed to clean images at 14:20 UTC.
Check for these artifacts:
- cook.pth, cook.py and sitecustomize.py in site-packages.
- /tmp/.pc_once_72129118c59f5636c0bb, which means exfiltration already fired.
- /tmp/remote_code_loader.lock, which means the loader daemon ran or is running.
A missing marker does not clear a host. Failed uploads, temp cleanup and container replacement all leave no marker (Endor Labs, Microsoft Security Blog).
What to do now
- Do not start python or pip inside a suspect environment to investigate. Microsoft and Datadog warn that doing so triggers the malware again. Inspect the files from outside the environment.
- Kill any detached Python process holding /tmp/remote_code_loader.lock, then manually delete cook.pth, cook.py and sitecustomize.py from site-packages. Deleting the litellm package directory does not remove them (Datadog Security Labs).
- Remove all code and data from the 1.107.0 release. Roll back to litellm==1.106.2 (or a later clean release, which StepSecurity says resumed on October 24), and pin images by digest rather than by latest or main-stable. Rebuild affected containers instead of cleaning them in place.
- From a clean machine, rotate every credential the host could reach: - Cloud keys and instance roles, Kubernetes, Docker, Vault and Terraform secrets. - SSH, GPG and TLS keys, and Git, npm and PyPI tokens. - .env contents and every environment variable on the host. - Browser passwords and cookies. - AI tool sessions and LLM provider API keys, including every key stored in the LiteLLM proxy database (LiteLLM_CredentialsTable).
- Audit cloud and CI logs for use of exposed credentials since October 21. Look for sts:GetCallerIdentity and Bedrock model listing calls, IAM enumeration, and traffic from 168.100.8[.]57 or 165.227.201[.]8 (Wiz).
- Block litellm[.]dev and hunt for outbound POSTs to /healthcheck carrying the header X-Token: XWiA8gZNa7NcX2XRoAEb. Also look for requests to raw.githubusercontent[.]com/letters9813/pythonclient-test/main/domain.txt.
- Compare any installed wheels against the published SHA-256 hashes in the Datadog, Aikido and Wiz IOC tables.
- Maintainers should lock release workflows to approved repositories and treat developer CLI tokens as high-value secrets (Datadog Security Labs).
Sources
- Datadog Security Labs: LiteLLM supply chain compromise, what you need to know
- Aikido: LiteLLM compromised, infostealer and RAT in PyPI 1.107.0
- Wiz: LiteLLM Compromised, Steals Credentials
- Endor Labs: LiteLLM 1.107.0 Compromised, Python Startup Hooks Steal Cloud, AI, and Proxy Credentials
- Microsoft Security Blog: Inside the LiteLLM 1.107.0 supply chain compromise
- StepSecurity: litellm 1.107.0 Compromised on PyPI and Docker