2026-10-21 · 2026-Q4
LiteLLM 1.107.0 on PyPI and Docker Ships a Credential Stealer That Runs at Every Python Startup
PrimaryL1CredentialSecondaryL7Build / ApprovalL4Code / PackageL8Output / Destination
- Fixable:
- Yes, vendor patch
- Vendor response:
- Patched
- In the wild:
- Yes
- Actor:
- Attacker
Target
BerriAI LiteLLM: all PyPI `litellm` 1.107.0 wheels and the `v1.107.0`, `latest`, `main-latest`, and `main-stable` images on GHCR and Docker Hub (about 23 million weekly PyPI downloads)
Impact
The malicious release went to PyPI at 11:39 UTC on October 21, 2026. Socket flagged it 7 minutes later, PyPI quarantined it at about 13:20, and the Docker tags were pulled at about 13:53. It drops `cook.pth`, `cook.py`, and `sitecustomize.py` into site-packages, so the payload runs on every interpreter start even if LiteLLM is never imported. The stealer takes cloud, Kubernetes, SSH, GPG, and registry credentials, AI provider keys and AI coding tool auth files, browser data, and shell history. Where a proxy database is configured, it also queries LiteLLM's stored provider credential tables. Data is encrypted and POSTed to the lookalike domain `www.litellm[.]dev`. A Linux and macOS loader polls a GitHub dead-drop hourly for a second stage, which was never populated. Wiz says the `.pth` plus `sitecustomize.py` persistence pairing is a first documented in-the-wild case. Last safe version is 1.106.2. This is LiteLLM's second PyPI compromise of 2026
Root Cause
Build provenance shows the release workflow building from the lookalike repository `Berri-AI/litellm` (hyphenated), where 10 commits were pushed that morning. LiteLLM's October 23 root-cause analysis traces it to an internal Agent Platform master key committed to a public repository on May 27, 2026 and force-pushed over but never revoked. On October 10 the attacker used it to call the platform's agent-listing API, which returned an organization owner's GitHub CLI OAuth token; workflow runs then dumped repository secrets holding two more maintainers' tokens, which were used to disable branch protection, trigger the release, and meet the two-approver rule