Skip to main content

LiteLLM 1.107.0 on PyPI Shipped a Credential Stealer and a Backdoor

Every wheel of LiteLLM 1.107.0 published to PyPI on 21 October carried a .pth credential stealer and a sitecustomize.py backdoor that ran in every Python process on the host, collecting SSH keys, cloud credentials and AI tool tokens, and polling a GitHub-hosted address hourly for second-stage code. The upstream GitHub source was clean; an attacker used stolen developer credentials to publish. PyPI removed the release within three hours.

On this page

What the malicious wheels did

The compromise was elegant in the worst way. One injected line in pyproject.toml, data = "cook", told the build tool to bundle a folder into the wheel's purelib data, so every install put three files at the root of site-packages: cook.pth containing import cook, cook.py, and sitecustomize.py. Because Python executes import lines in .pth files and imports sitecustomize at startup, the payload ran "each time any Python process starts in that environment", whether or not that process ever imported litellm.

The stealer cast a wide net. SafeDep's analysis lists SSH keys, shell history, cloud credentials from AWS and gcloud and Kubernetes, CI and CD secrets for GitLab, Jenkins, Vault and Terraform, tokens for AI coding tools including Claude Code, Cursor and Copilot, browser passwords, GPG and TLS keys, and the LiteLLM proxy database tables that hold users' LLM provider API keys. Everything was encrypted with AES-256-CBC and posted to a look-alike domain, www.litellm[.]dev, disguised as a healthcheck. The second file was quieter: sitecustomize.py forked a detached daemon that woke every hour, read a command server address from a GitHub dead-drop file, and downloaded whatever Python code was published there. The daemon used os.fork and so failed on Windows, but the stealer ran there regardless.

How the attacker got in

The upstream GitHub repository was clean: no public commit in BerriAI/litellm contains the payload. The malicious artifacts existed only in the prebuilt wheels on PyPI and in Docker images published under the v1.107.0, latest, main-latest and main-stable tags.

Getting them there took credentials, not exploits. LiteLLM's own incident account says the attacker held GitHub credentials belonging to three developers, likely harvested from an internal LiteLLM deployment exposed to the internet, overrode branch protection with an organization owner token, and passed the release approval gate with a second developer's credential. The malicious wheels went up at 11:39 UTC on 21 October; PyPI removed the release at 13:23, and the Docker tags were pulled or repointed by 14:20.

It was also a repeat. In March 2026 the TeamPCP group used a stolen PyPI token to publish compromised versions 1.82.7 and 1.82.8. LiteLLM rotated maintainer accounts after that incident, yet this release still reached PyPI and Docker Hub through what Chainguard calls a path nobody has yet explained.

What LiteLLM users should do now

1.106.2, 1.107.0rc1 and 1.107.0rc2 are clean; pin one of those and pull images by digest rather than by tag. If 1.107.0 was installed, the order of operations matters: do not run Python or pip on the host before deleting cook.pth, cook.py and sitecustomize.py with shell tools, because a pip uninstall re-runs the payload. Then kill any process holding /tmp/remote_code_loader.lock, check hosts for the /tmp/.pc_once_ markers and the PRIVCOLLECT_ACTIVE environment variable, and treat every credential the host could reach as compromised, including LiteLLM master keys and every provider key in its credentials table.

This matters beyond LiteLLM's own user base. The proxy is a common front door for self-hosted and local model stacks, which means the stolen provider keys and proxy databases are exactly the secrets a local-AI operator accumulates. A supply-chain attack on the tooling around local models lands on the same people who moved off hosted AI to reduce their exposure. Pin versions, verify digests, and treat any tool that can read your environment as part of your threat model.

CuriousLM runs supported AI models locally on your device. Try CuriousLM.