# LiteLLM PyPI Package and Docker Images Compromised to Steal Cloud and AI Credentials

Malicious LiteLLM 1.107.0 wheels and Docker images shipped Python startup hooks that harvested cloud, AI-tool and browser credentials and exfiltrated them to an attacker endpoint.

- Payout: Real-world hack
- Severity: critical
- Program: LiteLLM
- Credited: Socket Research Team
- Disclosed: 2026-10-21
- Write-up quality: 8/10
- Original: https://socket.dev/blog/litellm-compromise
- Library page: https://bugbountylibrary.com/r/blog%3Asocket-dev-blog-litellm-compromise
- Tags: domain:oss impact:data-leak impact:internal-access kind:incident platform:threat-intel sev:critical tech:ci-cd tech:docker tech:python technique:source-review vuln:misconfiguration vuln:secrets-leak

**Target:** PyPI package and GHCR/Docker Hub container images (Python startup hooks)
**Root cause:** Release workflow recorded a lookalike source owner (Berri-AI vs BerriAI) and a Maturin `data = "cook"` setting plus `COPY cook ./cook` in Dockerfiles injected cook.pth/cook.py/sitecustomize.py into builds, so Python site initialization executed the payload on any interpreter start.
**Steps:**
1. Identify litellm==1.107.0 wheels containing `litellm-1.107.0.data/purelib/cook.pth`, `cook.py`, `sitecustomize.py`
2. Inspect container provenance: dispatch inputs show `"source_owner": "Berri-AI"` and vcs source `https://github.com/Berri-AI/litellm` at revision `20535d8fa11f786a6c24df7488a0e449ed5f09ad`
3. Note commit `783c43bc455d2e05d3cfaf194c2f325cfeab1433` adds `data = "cook"` to `[tool.maturin]`; later commit adds `COPY cook ./cook` to backend/gateway/migrations Dockerfiles
4. `cook.pth` contains `import cook`; on any Python startup the collector runs in a daemon thread and sets `PRIVCOLLECT_ACTIVE=1`
5. Decode Base64+zlib payloads (~61KB) to recover 16 collection modules (AWS/Azure/GCP/K8s/Docker/Vault, SSH/GPG/TLS keys, .env, AI tool creds, browser DBs, env vars, IMDS)
6. Prisma child queries `SELECT "credential_name","credential_values" FROM "LiteLLM_CredentialsTable" LIMIT 500` and `LiteLLM_ProxyModelTable`
7. Collector AES-256-CBC encrypts JSON, wraps key with embedded RSA-4096 OAEP, tars `hdr.json`/`data.bin`/`key.bin`, POSTs to `hxxp://www.litellm.dev/healthcheck` with `X-Token: XWiA8gZNa7NcX2XRoAEb`
8. `sitecustomize.py` forks detached loader polling `raw.githubusercontent.com/letters9813/pythonclient-test/main/domain.txt`, then fetches `http://<domain>/codepy` and `exec(compile(...))` with no signature check, 3600s loop
**How found:** Socket's AI scanner flagged the seven wheels seven minutes after publication; static analysis of wheel contents and container provenance revealed the hyphenated source owner and the Maturin data-directory injection.
**Exploitation:** Attacker-controlled lookalike repo and release workflow produced signed-looking wheels and images; on install, Python startup hooks auto-executed the stealer without importing litellm, harvesting credentials and exfiltrating encrypted archives to the attacker endpoint, while a separate loader enabled remote Python execution.
**Escalation:** Floating tags (latest, main-latest, main-stable) resolved to the malicious image index, widening exposure beyond explicit 1.107.0 pinning; loader allowed arbitrary remote code on top of credential theft.
**Insight:** Diff build provenance `source_owner`/vcs source against the canonical repo and check wheel `.data/purelib` for `.pth`/`sitecustomize.py`; a one-character owner difference and a `data =` Maturin setting are the tell, and the tag's pyproject.toml won't show it.
