LiteLLM compromised again: version 1.107.0 ships infostealer and RAT

CriticalCompromisePyPI

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 21 Oct 2026

At a glancepypi-2026-10-21-litellm-infostealer-rat
1
Package tracked1 malicious version

Every version named by the advisory is in the scanner, so a lockfile check finds it directly.

Severity
Critical
Type
Compromise
Published
21 Oct 2026
Ecosystems
PyPI
Detected by
JFrog Security Research, Aikido Security
Also known as
LiteLLM 1.107.0 compromise, litellm privcollect stealer, cook.pth PyPI backdoor October 2026

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.

What happened

The full picture

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.
  1. 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
  1. 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.

infostealercredential-theftaccount-takeoverobfuscation
Affected packages

1 package 1 version

These are usually pulled in as transitive dependencies rather than installed directly. Check your whole tree at once. It runs in your browser and nothing is uploaded.

Impact

What it does if you installed it

  • 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

Clean-up steps

  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
References

Sources

pypi-2026-10-21-litellm-infostealer-ratBack to incidentsSubmit a correction
Am I affected?

Check your lockfile against this and every other incident.

Paste a lockfile and it is matched on your own device against every compromised version we track. Nothing is uploaded and there is no account.