BREAKING: LiteLLM 1.107.0 on PyPI and Docker latest shipped a credential stealer. Pin 1.106.2 and rotate your AI keys
How to fix the LiteLLM 1.107.0 compromise: pin litellm to 1.106.2, rebuild from a clean image, and rotate every key the host could read. All 1.107.0 wheels on PyPI and the Docker latest, main-latest and main-stable tags shipped a credential stealer that also dumps the proxy's stored provider keys.
Contents
If you installed or pulled LiteLLM 1.107.0 this morning, a credential stealer ran on that machine and sent out whatever keys it could find, including the AI provider keys your LiteLLM proxy stores. All seven 1.107.0 wheels on PyPI carried the malware. They went up at 11:39 UTC (7:39 AM ET) on October 21, and PyPI has since removed the release. The bigger problem is Docker. When we checked at 13:44 UTC (9:44 AM ET), latest, main-latest and main-stable on ghcr.io/berriai/litellm and docker.io/litellm/litellm still pointed at the same image digest as v1.107.0, which the public incident report says contains the stealer. If you deploy the proxy from a floating tag, assume any pull since 11:48 UTC is infected. There is no CVE for this yet. It is a supply-chain compromise, not a code bug.
This is our operator read of AISLE's analysis, the public incident report in BerriAI/litellm issue #47826, and the registry state we checked ourselves on GHCR and Docker Hub. When we published, BerriAI had not posted a statement on the issue.
How to fix
Pin LiteLLM to 1.106.2, the last release reported clean, and rebuild anything that installed 1.107.0. Do not just run pip install -U inside an infected environment: the malware lives outside the litellm package and runs every time Python starts.
# Python / SDK users: build a fresh environment, don't patch the old one
python -m venv /path/to/new-venv
/path/to/new-venv/bin/pip install 'litellm==1.106.2'
# Docker proxy users: pin the clean tag by digest, never latest/main-stable today
docker pull ghcr.io/berriai/litellm:v1.106.2
docker inspect --format '{{index .RepoDigests 0}}' ghcr.io/berriai/litellm:v1.106.2
# expect ...@sha256:7294b90f868c5c38c99b83021c7ba46f9b439e95f8e32964c925c7d2563a03f7
# then use image: ghcr.io/berriai/litellm@sha256:7294b90f868c5c38c99b83021c7ba46f9b439e95f8e32964c925c7d2563a03f7
Then rotate. Removing the package does not un-steal anything. If 1.107.0 ran, rotate every credential that machine or container could read: the LiteLLM master key, every upstream provider key stored in the proxy database (OpenAI, Anthropic, Bedrock, Vertex, Azure), the database password, cloud keys and instance roles, SSH keys, CI/CD tokens, Kubernetes service account tokens, and secrets in environment variables of other processes on the host.
Check whether you got it
# 1. Which version and which image digest are running?
pip show litellm | grep -i ^version
docker images --digests | grep -i litellm
# infected digest (v1.107.0 / latest / main-stable / main-latest):
# sha256:1bbcb1443bc962e45f5aad53fe3d2c30600e0379715fb6c664cdd3ac126c339e
# 2. The payload files sit in site-packages root, not inside litellm/
python -c "import site; print('\n'.join(site.getsitepackages()))"
find / -path '*site-packages*' \( -name cook.pth -o -name cook.py \) 2>/dev/null
find / -name sitecustomize.py -path '*site-packages*' -newermt '2026-10-21' 2>/dev/null
# 3. Marker and lock files the malware leaves
ls -la /tmp/.pc_once_72129118c59f5636c0bb /tmp/remote_code_loader.lock 2>/dev/null
On the network side, look in proxy, DNS and egress logs for www.litellm.dev (a lookalike; the real project is litellm.ai), HTTP requests carrying the header X-Token: XWiA8gZNa7NcX2XRoAEb, and fetches of raw.githubusercontent.com/letters9813/pythonclient-test/main/domain.txt. AISLE lists the exfiltration host behind Cloudflare at 104.26.10.8, 104.26.11.8 and 172.67.73.104, so block the hostname, not just the IPs.
Found any of it? Treat the host as compromised. Kill any Python process holding /tmp/remote_code_loader.lock, rebuild from a clean image, and rotate as above.
What the malware does
Each 1.107.0 wheel adds three files under litellm-1.107.0.data/purelib/, which pip copies straight into site-packages:
cook.pthholds one line,import cook. Python executesimportlines in.pthfiles at every interpreter start, so the stealer runs even if your code never imports LiteLLM.cook.pyis a compressed, base64-wrapped stealer. Per the incident report it collects host and network info, browser saved passwords and cookies, SSH keys, shell histories, AWS, Azure, GCP, kube and Docker credentials, package registry tokens,.envfiles and private keys, CI and Vault tokens, AI coding tool configs, and the environment of every readable process. IfDATABASE_URLis set, it dumps LiteLLM's own credential and model tables, which is where the proxy keeps your provider keys. It encrypts the bundle and POSTs it tohttp://www.litellm.dev/healthcheck.sitecustomize.pycarries a second copy plus a loader that forks into the background and checks a GitHub file every hour for a domain to download and run more code from. AISLE found that file empty when it looked, so the second stage was not armed yet. The attacker can arm it by editing one file.
How it got in
The v1.107.0 git tag on BerriAI/litellm is clean. The incident report shows the sdist's pyproject.toml has one line the tag does not, data = "cook" under [tool.maturin], so the build tree was changed between checkout and build. Its later update says the release was built from a lookalike repository, Berri-AI/litellm. That is the reporter's finding, not yet confirmed by BerriAI. One detail matters for defenders: Docker Hub lists a cosign signature object for the infected digest, so a passing cosign verify on today's image is not evidence it is clean. Pin by digest and check it against a known-good value.
This is the second time this year. In March, LiteLLM 1.82.7 and 1.82.8 on PyPI were compromised through the Trivy dependency in its CI. Back then BerriAI said the official proxy Docker image was not affected. This time the Docker image is the path most proxy operators use.
Who is not in scope
- Anyone pinned to 1.106.2 or earlier in a lockfile, or running a Docker image pinned to a version tag other than
v1.107.0. The incident report checked every wheel from 1.103.6 through 1.106.2 and the 1.107.0 release candidates and found them clean. - Anyone who built 1.107.0 from the sdist. It has the tampered
pyproject.tomlbut not the payload files. Move off it anyway. - Installs that happened after PyPI removed 1.107.0.
pip install litellmnow resolves to 1.106.2.
What this is not
This is not a vulnerability in LiteLLM's code that an outsider can exploit over the network; the damage happens on machines that installed the poisoned build, and it is the theft of secrets from those machines.
References
Continue reading
All posts
Unsloth RCE: malicious Hugging Face model config.json injects code
How to fix CVE-2026-93348: upgrade unsloth-zoo to 2026.8.14+ and unsloth to 2026.8.20+

BREAKING: PHP2Shell lets attackers run code on PHP web servers with no login. Update PHP now (CVE-2026-109618, CVE-2026-109619)
How to fix CVE-2026-109618: upgrade PHP to 8.5.12, 8.4.27, 8.3.36 or 8.2.35, then restart Apache and PHP-FPM. PHP2Shell (CVE-2026-109618 and CVE-2026-109619) lets attackers run code on PHP web servers with no login. PHP 8.1 and older get no upstream fix.

BREAKING: Plex Media Server hijacked without a login to mine crypto and run proxies, now on CISA KEV (Plex2Shell, CVE-2026-96652)
How to fix CVE-2026-96652: upgrade Plex Media Server to 1.43.3.10861 or later. The Plex2Shell chain (CVE-2026-96652, -96654, -96655, -96656) is exploited to install crypto miners and proxies, on CISA KEV Oct 20. Updating does not remove an infection.
