# LiteLLM compromised again: version 1.107.0 ships infostealer and RAT

> On 2026-10-21 JFrog and Aikido disclosed that `litellm` 1.107.0 on PyPI ships an infostealer and a remote-access trojan in all 7 compiled wheels. A `cook.pth` file triggers the stealer at every Python interpreter start, harvesting credentials across cloud providers, CI/CD, browsers, AI tools, and package registries, while a `sitecustomize.py` hourly RAT loop fetches remote code from a GitHub dead-drop.

- Published: 2026-10-21
- Severity: critical
- Kind: Compromise - A legitimate, already-used package, maintainer account, CI pipeline, or release tag was hijacked and a malicious version was published under a name people already depend on.
- Ecosystems: PyPI
- Scope: 1 package, 1 compromised version
- Tags: infostealer, credential-theft, account-takeover, obfuscation
- Also known as: LiteLLM 1.107.0 compromise, litellm privcollect stealer, cook.pth PyPI backdoor October 2026
- Detected by: JFrog Security Research, Aikido Security
- Incident ID: pypi-2026-10-21-litellm-infostealer-rat

## Affected packages (1)

Only the exact versions listed were named by the source advisories. Other versions are not implicated.

| Package | Ecosystem | Compromised versions |
|---|---|---|
| [litellm](https://dependencywatch.io/package/pypi/litellm) | PyPI | 1.107.0 |

## What happened

On **2026-10-21** JFrog Security Research published a detailed analysis and Aikido Security issued a public alert: `litellm` version `1.107.0` on PyPI had been backdoored with an infostealer and a remote-access trojan. All 7 compiled wheels (macOS x86_64, macOS ARM64, manylinux aarch64/x86_64, musllinux aarch64/x86_64, Windows amd64) contain three malicious files. PyPI quarantined the release the same day. GitHub issue `BerriAI/litellm#47826` was filed at 12:06 UTC.

This is the **second compromise of LiteLLM in 2026**. The first, on 2026-03-24, was part of the TeamPCP cascade: credentials stolen from a poisoned Trivy scanner were used to publish trojanised versions 1.82.7 and 1.82.8. JFrog states there is **no evidence linking the 1.107.0 attack to TeamPCP**; they should be treated as separate campaigns.

## Attack vector

The release was built from a **lookalike repository `Berri-AI/litellm`** (note the hyphen vs the legitimate `BerriAI/litellm`). Payload files share ZIP timestamps with legitimate wheel files, suggesting injection during wheel construction rather than post-build repacking. How PyPI publishing access was obtained has not been confirmed.

## Payload

Three files work together:

1. **`cook.pth`** — a single `import cook` line. Python's `site` module runs `.pth` files at every interpreter startup, so the stealer executes even if `litellm` is never imported.

2. **`cook.py`** — decodes (Base64 + zlib) and `exec()`s a ~61 KB program called `privcollect`. Runs in a daemon thread, uses a run-once marker file, and sets `PRIVCOLLECT_ACTIVE=1`. The stealer targets:
   - SSH, GPG, and TLS private keys; `.pem`/`.key`/`.p12`/`.pfx` files
   - Chromium and Firefox passwords, cookies, history, key databases
   - AWS, Azure, GCP credentials; Kubernetes configs and service-account tokens; Docker/Swarm secrets
   - CI/CD: GitLab Runner, Jenkins, Vault, Terraform, Packer
   - Package registries: `.git-credentials`, `.npmrc`, `.pypirc`, pip, Yarn, Maven, Gradle, Composer, RubyGems, Cargo
   - AI tool credentials: Cursor, Claude, Codex, Gemini, Copilot, Hugging Face, and others
   - Every readable `/proc/<pid>/environ` on Linux
   - Cloud instance metadata (AWS IMDS/ECS, GCP, Azure IMDS)
   - LiteLLM proxy DB via `DATABASE_URL` → `LiteLLM_CredentialsTable` and `LiteLLM_ProxyModelTable`

3. **`sitecustomize.py`** — forks at startup, takes a non-blocking lock at `/tmp/remote_code_loader.lock`, and loops hourly to fetch a C2 domain from a GitHub dead-drop (`raw.githubusercontent.com/letters9813/pythonclient-test/main/domain.txt`). If a domain is returned, downloads `/codepy` over plaintext HTTP and `exec()`s it. On Windows the fork fails silently but `cook.pth` still runs the stealer.

## Exfiltration

Harvested data is packaged as a tar.gz archive containing AES-256-CBC-encrypted data with an RSA-4096-wrapped key, sent to `www[.]litellm[.]dev/healthcheck` over plaintext HTTP with `X-Token` and `X-SHA256` headers. The exfiltration domain is a typosquat of the legitimate `litellm.ai`.

## Cross-reference

The March 2026 TeamPCP compromise (versions 1.82.7, 1.82.8) used the same `.pth` persistence technique but exfiltrated to different infrastructure (`models.litellm.cloud`, `checkmarx.zone`). That incident is tracked separately as `pypi-2026-03-24-litellm-teampcp`. The reuse of `.pth` persistence across two independent campaigns targeting the same package underscores that LiteLLM's position in the AI/LLM toolchain makes it a high-value target for supply-chain operators.

JFrog tracks this incident as XRAY-955589. No GHSA or CVE has been assigned at time of writing.

## Impact

- **All 7 platform wheels backdoored**: macOS x86_64, macOS ARM64, manylinux aarch64, manylinux x86_64, musllinux aarch64, musllinux x86_64, and Windows amd64 wheels all contain the payload. The source tarball lacks the payload files but has a tampered `pyproject.toml` (`data = "cook"`)
- **`.pth` persistence fires on every interpreter start**: `cook.pth` imports `cook`, which runs at every Python interpreter startup via the `site` module, not only when `litellm` is imported. Any Python process on the host triggers the stealer, identical to the March 2026 `.pth` technique
- **Comprehensive credential harvesting**: the `privcollect` stealer targets SSH/GPG/TLS private keys, Chromium and Firefox passwords and cookies, AWS/Azure/GCP credentials, Kubernetes configs and service-account tokens, Docker/Swarm secrets, CI/CD tokens (GitLab Runner, Jenkins, Vault, Terraform), package registry credentials (`.npmrc`, `.pypirc`, `.git-credentials`, Maven, Gradle, Composer, Cargo), cloud instance metadata (AWS IMDS/ECS, GCP, Azure IMDS), every readable `/proc/<pid>/environ` on Linux, and the LiteLLM proxy database itself via `DATABASE_URL`
- **AI tool credentials explicitly targeted**: Cursor, Claude, Codex, Gemini, Copilot, Hugging Face, and approximately a dozen other AI tool credential stores are in the stealer's target list
- **Hourly RAT loop with GitHub dead-drop**: `sitecustomize.py` forks at startup, polls `raw.githubusercontent.com/letters9813/pythonclient-test/main/domain.txt` hourly, and exec()s whatever it downloads from the returned domain over plaintext HTTP. The dead-drop was empty at time of analysis but changing the file re-arms every infected host
- **Docker images still infected at disclosure**: `latest`, `main-latest`, and `main-stable` tags on `ghcr.io/berriai/litellm`, `ghcr.io/berriai/litellm-database`, `ghcr.io/berriai/litellm-non_root`, and `docker.io/litellm/litellm` pointed to v1.107.0 at time of disclosure
- **LiteLLM averages ~95M monthly PyPI downloads**: exposure window is not yet quantified but any `pip install litellm` without a version pin during the window pulled 1.107.0

## What to do

1. Check `pip list`, `pip freeze`, lockfiles, and Docker image manifests for `litellm==1.107.0`. Uninstall on hit and pin to `litellm==1.106.2` (the last clean release). Do NOT upgrade in an affected environment: rebuild clean
2. Delete `cook.pth`, `cook.py`, and `sitecustomize.py` from `site-packages` on every host that installed 1.107.0. Remove `/tmp/remote_code_loader.lock` and any marker files left by the stealer
3. Treat every host that ran `litellm==1.107.0` as fully compromised. Rotate: SSH/GPG keys, cloud provider credentials (AWS/GCP/Azure), Kubernetes service-account tokens, CI/CD tokens, package registry credentials (`.npmrc`, `.pypirc`, `.git-credentials`), browser passwords, and AI tool API keys (Claude, Cursor, Copilot, Gemini, Hugging Face)
4. If running the LiteLLM proxy, rotate `DATABASE_URL` and any credentials stored in `LiteLLM_CredentialsTable` and `LiteLLM_ProxyModelTable`
5. For Docker deployments: pin images by digest to a known-clean version. Do not trust `:latest`, `:main-latest`, or `:main-stable` tags until BerriAI confirms the images have been rebuilt
6. Block egress to `www.litellm.dev` (the exfiltration endpoint, distinct from the legitimate `litellm.ai`) and to `raw.githubusercontent.com/letters9813/pythonclient-test/` (the RAT dead-drop)
7. Alert on processes making plaintext HTTP connections to unknown domains from hosts that run Python workloads, particularly with `X-Token` and `X-SHA256` headers

## Check your own dependencies

- Check a requirements.txt against this incident: https://dependencywatch.io/check/requirements-txt

The scan runs entirely in the browser; lockfile contents are never uploaded.

## References

- [LiteLLM Hijacked Again — infostealer and RAT in version 1.107.0](https://research.jfrog.com/post/litellm-hijacked-again/) - JFrog
- [BerriAI/litellm issue #47826 — litellm 1.107.0 compromised](https://github.com/BerriAI/litellm/issues/47826) - GitHub

---

Canonical page: https://dependencywatch.io/incident/pypi-2026-10-21-litellm-infostealer-rat
Markdown version: https://dependencywatch.io/incident/pypi-2026-10-21-litellm-infostealer-rat.md
Site index for agents: https://dependencywatch.io/llms.txt
DependencyWatch.io is operated by Precursor Security (https://precursorsecurity.com).
