
LiteLLM got hit again. On October 21, 2026, a malicious version of one of the most widely-used AI gateway libraries shipped through PyPI and Docker Hub with a credential stealer and a persistent remote-access backdoor baked in. The official incident report, published the same day and last updated at 16:00 (UTC), lays out exactly how three stolen developer tokens turned a routine release into a supply-chain nightmare that lasted roughly two hours.
This is not the first time. In March 2026, the TeamPCP group poisoned LiteLLM versions 1.82.7 and 1.82.8 after compromising the Trivy vulnerability scanner used in LiteLLM's CI pipeline. That attack lived on PyPI for about 46 minutes. The October attack is worse in almost every dimension: a longer exposure window, all seven platform builds compromised, Docker images including the latest tag, and a more sophisticated dual-payload implant.
What actually happened
At 10:08:29 (UTC) on October 21, GitHub's branch protection rejected an unauthorized change to LiteLLM's private release workflow. Five seconds later, at 10:08:34 (UTC), a credential belonging to a privileged developer account overrode those protections and pushed a malicious workflow commit. That single override set everything in motion.
The attacker used one developer's account to modify the release pipeline and trigger a staging build from an attacker-controlled repository (Berri-AI/litellm at a specific commit). A second developer's credential approved the production release gate at 11:11:18 (UTC). By 11:39:51 (UTC), seven malicious wheels for litellm==1.107.0 were uploading to PyPI. Docker images followed at 11:46:56 (UTC). A third developer account was then used at 11:53:49–11:54:01 (UTC) to delete the production and staging workflow records, limiting the logs available for investigation.
PyPI pulled the package by 13:23 (UTC). Docker Hub tags were cleaned by 14:20 (UTC). The malicious GitHub account letters9813, which hosted the backdoor's command-and-control configuration, was deleted around 13:40 (UTC).
| Time (UTC) | Event |
|---|---|
| 10:08:29 | Branch protection blocks unauthorized workflow change |
| 10:08:34 | Privileged developer credential overrides protection |
| 10:46:39 | Staging build starts from attacker-controlled repo |
| 11:11:18 | Second developer credential approves production gate |
| 11:39:51 | Seven malicious wheels uploaded to PyPI |
| 11:46:56 | Compromised Docker images published |
| 11:53:49 | Third developer credential deletes workflow logs |
| 13:23 | PyPI removes litellm==1.107.0 |
| 14:20 | All Docker tags cleaned or repointed |
Source: LiteLLM official incident report, docs.litellm.ai/blog/security-incident-oct-21-2026
The malware, dissected
Security firm SafeDep reverse-engineered the implant and published a full technical breakdown. The malicious wheel drops three files into Python's site-packages:
cook.pth(12 bytes): Contains simplyimport cook. Python executes everyimportline in a.pthfile at interpreter startup, so this runs in every Python process on the host — your app, pip, IDE language servers, CI jobs.cook.py(22,252 bytes, ~61 KB decoded): The credential stealer. Wrapped inexec(zlib.decompress(base64.b64decode(...)))to evade casual inspection.sitecustomize.py(25,509 bytes): A persistent backdoor daemon. Python importssitecustomizeautomatically at startup, so this also runs in every process.
The stealer targets 16 categories of secrets:
| Module | What it steals |
|---|---|
browser_pw |
Chromium saved passwords (DPAPI-decrypted on Windows), Firefox logins |
ssh_keys |
~/.ssh/* private keys |
cloud_creds |
AWS credentials, Azure tokens, gcloud, kubeconfig, Docker config, .netrc |
dev_secrets |
.pem/.key/.pfx files, Composer auth, FileZilla servers |
cicd_secrets |
GitLab runner config, Jenkins master.key, Vault token, Terraform credentials |
ai_devtools |
Claude Code/Desktop, Cursor, Windsurf, Copilot, Codex, Gemini CLI, Hugging Face tokens |
db_litellm |
Dumps the LiteLLM proxy database — every LLM provider API key |
env_vars |
Reads /proc/<pid>/environ for other processes' environment variables |
gpg_keys, tls_privkey |
GPG and TLS private keys |
Source: SafeDep analysis, safedep.io/litellm-pypi-compromise-credential-stealer-backdoor
Collected data is encrypted with AES-256-CBC using a random key, which is then encrypted with an embedded RSA-4096 public key. The bundle is POSTed to www.litellm.dev/healthcheck with a hardcoded X-Token header. A marker file at /tmp/.pc_once_72129118c59f5636c0bb ensures the stealer runs only once per host — unless the backdoor reruns it.
The backdoor is where things get nasty. sitecustomize.py forks a detached daemon (parent PID 1, own session, working directory /) that wakes up every 3,600 seconds. Each cycle it reads a domain from a GitHub raw file (letters9813/pythonclient-test/main/domain.txt), runs the stealer again (this time with no once-per-host limit), and downloads code from http://<domain>/codepy to execute via exec(). The attacker can redirect every infected machine to a new server simply by editing that GitHub file.
How it got past every safeguard
The official report identifies the root cause plainly: three engineers' GitHub CLI OAuth tokens were stolen. The attacker used one account to bypass branch protection and modify the release workflow, a second to approve the production gate, and a third to delete evidence.
The injection itself is elegant in its simplicity. The pyproject.toml in the malicious source distribution gained one line in the maturin build section: data = "cook". This tells the build system to copy a cook/ folder into the wheel's purelib directory, which pip then installs into site-packages. The official GitHub tag v1.107.0 does not contain this line or the cook/ folder — the malicious wheels were built from an attacker-controlled mirror, not from the public source.
AISLE, a dependency firewall company, caught the credential stealer 3 minutes and 14 seconds after the release went live. JFrog Security Research and StepSecurity also published independent analyses. No CVE has been assigned; the official GitHub source tag is clean, which makes this a supply-chain compromise rather than a code vulnerability.
Who is affected — and what to do
You are affected if you ran pip install litellm (unpinned) between 11:39 and 13:23 (UTC) on October 21, or pulled Docker tags v1.107.0, latest, main-latest, or main-stable between 11:46 and 14:20 (UTC). The last confirmed safe version is 1.106.2. Enterprise customers pulling from LiteLLM's private registry were not affected.
The remediation order matters. LiteLLM's advisory explicitly warns: do not start with pip install. Any Python startup in the infected environment re-runs cook.pth and sitecustomize.py, including pip itself. The correct sequence is:
- From the shell, delete
cook.pth,cook.py,sitecustomize.py, and matching__pycache__files from every affectedsite-packages. - Kill the detached Python daemon holding
/tmp/remote_code_loader.lock. - Reinstall pinned to
litellm==1.106.2. Rebuilding virtual environments and images from scratch is safer than cleaning in place. - If 1.107.0 ever ran on a host with outbound internet, assume exfiltration succeeded. Rotate every secret that host could reach: instance IAM roles, all LLM provider keys in the LiteLLM proxy database,
DATABASE_URLpasswords, and every environment variable. - Check CloudTrail for
GetCallerIdentityfrom the instance role around install time, then for credential use from outside your infrastructure.
Why this matters beyond one library
LiteLLM is downloaded more than 23 million times. It sits at a uniquely dangerous position in the AI stack: a single proxy that holds API keys for OpenAI, Anthropic, Google, and every other provider an organization uses. Compromise the proxy, and you compromise every model budget, every customer conversation flowing through it, and every cloud credential in its environment. The db_litellm module in the stealer exists for exactly this reason — it dumps the entire credentials table from the proxy database.
The repeat nature of this attack is the real story. Seven months after TeamPCP poisoned versions 1.82.7 and 1.82.8 via a compromised Trivy scanner, a different attacker walked through a different door — stolen developer OAuth tokens — and achieved the same outcome. LiteLLM has now been the vector for two major supply-chain incidents in a single year. The March attack used litellm_init.pth and exfiltrated to checkmark.zone; the October attack uses cook.pth + sitecustomize.py and exfiltrates to litellm.dev. Different malware, same target, same trust model failure.
There is also a ticking clock. LiteLLM's advisory mentions that its private enterprise registry is distributing "an embargoed release that remediates a vulnerability whose disclosure date is scheduled for October 27." That means a separate, undisclosed vulnerability in LiteLLM will become public in four days. Organizations running LiteLLM in any environment should assume the next week will bring more bad news, not less.
The broader pattern is unmistakable: AI infrastructure dependencies are becoming the prime target for supply-chain attacks because they concentrate credentials. A single compromised package can yield OpenAI keys, AWS credentials, SSH keys, and CI/CD tokens simultaneously. Traditional software supply-chain controls — artifact signing, provenance attestation, branch protection — were all present here and all failed because the attacker controlled the human credentials that sit above them.
What to watch next
Monitor whether any organization confirms actual credential abuse from stolen LiteLLM proxy keys in the coming weeks. The exfiltration window was short, but organizations that auto-update Docker latest tags or run pip install in CI without pinning may have pulled the malicious version without knowing it. Watch for unexpected spikes in LLM API usage, unfamiliar cloud console logins, and new GitHub activity from developer accounts that use LiteLLM.
The October 27 embargoed vulnerability disclosure will likely dominate the next news cycle for this project. If that vulnerability is remotely exploitable in the proxy itself — rather than a release-pipeline issue — the combined risk of a known RCE plus a demonstrated supply-chain compromise could force many organizations to migrate away from LiteLLM entirely.
For the AI industry, the lesson is uncomfortable: the gateway layer that everyone built to centralize model access has become the single most valuable target in the entire stack. Every organization running an AI proxy should be auditing its dependency provenance, rotating all proxy-stored keys, and asking whether centralizing every API credential in one open-source component is still a risk worth taking.
No comments yet