LiteLLM 1.107.0 on PyPI and Docker was malware: a credential stealer that runs whenever Python starts
On 21 October 2026 a malicious litellm 1.107.0 was published to PyPI and pushed to LiteLLM's official Docker images. It adds Python startup hooks that steal credentials and set up an hourly remote-code loader, and it runs as soon as Python starts, even if you never import litellm.
What it is
LiteLLM's incident post: litellm==1.107.0 (all seven wheels) was live on PyPI from 11:39:51 to 13:23 UTC on 21 October. Docker Hub tags v1.107.0, latest, main-latest and main-stable pointed to the compromised image index sha256:1bbcb1443bc962e45f5aad53fe3d2c30600e0379715fb6c664cdd3ac126c339e from 11:46:56 to 14:20 UTC, and the same GHCR tags (litellm, litellm-database, litellm-non_root) until 13:51 UTC. The v1.107.0 source tag on GitHub is clean; the artifacts were built from an attacker-controlled lookalike repo (Berri-AI/litellm). Customers on the private enterprise release were not affected.
The package adds three files to site-packages: cook.pth (one line, "import cook"), cook.py (the credential collector) and sitecustomize.py (a detached loader). Python processes both on interpreter start, so any python or pip run in that environment triggers them. Microsoft saw a routine pip install of an unrelated dependency set it off on Windows.
The collector goes after SSH keys, cloud credentials (AWS, Azure, GCP, Kubernetes, Docker, gh), .env files, browser-stored passwords, AI tool configs (Claude, Cursor, Codex, Gemini and others), process environments and cloud metadata. If DATABASE_URL is set it also reads LiteLLM proxy tables holding provider credentials and model config. Data is POSTed to http://www.litellm.dev/healthcheck (LiteLLM's real domain is litellm.ai). The loader polls a GitHub dead-drop hourly and would exec() code from the domain it names. Microsoft says it hasn't confirmed any second-stage payload.
Root cause, per LiteLLM: stolen GitHub CLI OAuth tokens from engineers' accounts were used to get around branch protection and point the release pipeline at the lookalike repo. LiteLLM has since posted a canonical incident record that corrects parts of its first write-up, so read that for the latest.
Separately, LiteLLM says it is shipping an embargoed release to fix a different vulnerability whose public disclosure is scheduled for 27 October 2026. Watch for that advisory and update when it lands.
How to check
- Search lock files, requirements, uv/pip caches, internal mirrors and image build logs for litellm 1.107.0, and check whether you pulled latest, main-latest, main-stable or v1.107.0 images on 21 October.
- Look for the startup files from a clean shell, without running python or pip in the suspect environment (see the commands below).
- Look for /tmp/remote_code_loader.lock (the loader's lock) and /tmp/.pc_once_72129118c59f5636c0bb (written after a successful exfiltration), and for outbound traffic to www.litellm.dev.
- In AWS CloudTrail, look for unexpected GetCallerIdentity calls from those hosts' credentials after 21 October.
How to fix
- Isolate affected machines, containers and CI runners first. Don't start python or pip in them to investigate. Stop running Python processes, including the detached loader.
- Rebuild from scratch rather than uninstalling. Deleting the litellm directory leaves cook.pth, cook.py and sitecustomize.py behind. Pin litellm==1.106.2 (or a later clean release) and reference Docker images by digest, not by floating tags.
- If the host had internet access, assume secrets were exfiltrated. From a clean machine, rotate cloud IAM credentials, SSH keys, GitHub tokens, every provider API key stored in the LiteLLM proxy, the proxy master and virtual keys, the DATABASE_URL password and anything else in that environment.
- Going forward, pin dependencies with hashes, give new releases a cool-down before auto-upgrading, and keep CI tokens short-lived and scoped.
# Run from a shell, NOT via python/pip, inside the suspect environment
find / -path /proc -prune -o \( -name 'cook.pth' -o -name 'cook.py' -o -name 'litellm-1.107.0.dist-info' \) -print 2>/dev/null
find / -path /proc -prune -o -name 'sitecustomize.py' -path '*site-packages*' -print 2>/dev/null
ls -la /tmp/remote_code_loader.lock /tmp/.pc_once_72129118c59f5636c0bb 2>/dev/null
# Pin a known-good version
pip install 'litellm==1.106.2' Sources
- criticalCVE-2026-114612: LiteLLM proxy lets an internal user forge an admin token and run commands
- criticalCVE-2026-37004: LiteLLM vulnerable to server-side template injection in the /prompts/test endpoint
- criticalCVE-2026-49468: LiteLLM: Authentication Bypass via Host Header Injection
- criticalCVE-2026-42208: LiteLLM has SQL Injection in Proxy API key verification