Compromised LiteLLM 1.107.0 on PyPI shipped a credential stealer and backdoor
Translated by a model; the original is in Russian.
SafeDep researchers report that the LiteLLM 1.107.0 release on PyPI was compromised: all seven wheels (Linux, macOS, Windows) dropped three extra files into site-packages — a credential stealer and a backdoor. The upstream BerriAI/litellm source on GitHub contained none of them. PyPI has since pulled the release.
Neighbouring versions 1.106.2 and the 1.107.0rc1/rc2 candidates are clean, as are the companion packages litellm-proxy-extras and litellm-enterprise that the release pinned.
What the malware did
A file named cook.pth held the line import cook, so Python ran cook.py — the stealer — on every startup. It scooped up SSH keys, cloud credentials, CI/CD secrets, AI-tool tokens, browser passwords and the LLM-provider keys from a LiteLLM proxy database. Notably, its ai_devtools module targeted tokens for Claude Code, Cursor, Copilot, Gemini CLI and a dozen more assistants, while env_vars read other processes' environments through /proc/<pid>/environ.
The data was encrypted with an AES-256 key, the key itself wrapped with RSA, and POSTed to www.litellm[.]dev (not the project's own domain). The second file, sitecustomize.py, launched a background daemon: once an hour it read a server address from a GitHub file, ran the stealer again, and downloaded arbitrary code from that server to run via exec().
Because both files fired on the start of any Python process — the app, pip, IDE language servers, CI jobs — even a process that never imported LiteLLM got infected.
How the implant got in
The sdist's pyproject.toml had a single extra line — data = "cook" in the maturin section — which copied a cook/ folder into the wheel. The attacker also rolled the version number back from 1.108.0 to 1.107.0 and pinned the companion packages to the rc2 values, so a dependency diff against rc2 showed nothing unusual.
The built wheels match the output of BerriAI's normal release pipeline: the same maturin version, correct RECORD entries, separate native builds for all three platforms. In the Windows wheel every .py file has CRLF line endings — the fingerprint of a Windows checkout. SafeDep assesses, with moderate-to-high confidence, that BerriAI's private pipeline built the wheels from an attacker-modified source; only the pipeline's own logs can confirm the cause.
The aftermath
About two hours after publication, the letters9813 account that held the command-server address returned 404, and the backdoor could no longer find a server. But hosts that had already started the daemon could have fetched and run second-stage code. Affected users should check for the named files and /tmp indicators and rotate every secret the Python process could reach.
Source: Hacker News
Comments
Sign in, to comment.