L4 · Septic Tank Blewsupply chain · PyPI · Docker · AI · secretslitellm-pypi-compromise

LiteLLM, round two: your LLM gateway now proxies your keys to someone else

LiteLLM 1.107.0 on PyPI and Docker was a credential stealer with a remote-code loader, built from a lookalike repo

Attackers used stolen GitHub CLI tokens from three LiteLLM engineers to publish litellm 1.107.0 to PyPI and Docker from a lookalike repo. It steals cloud, AI and LiteLLM proxy keys on every Python start. Live ~2 hours.

Disclosed
Oct 21, 2026
Public disclosure date
Severity
Septic Tank Blew
No CVE: a breach, not a bug
Splash zone
Anyone who installed litellm 1.107.0 or pulled latest / main-latest / main-stable / v1.107.0 images on Oct 21
pypi · docker
In the wild
Yes
Wiz saw stolen AWS role credentials used from attacker IPs hours later

The one-sentence version

A hijacked release workflow built LiteLLM from an attacker's copy of the repo. The wheel drops a .pth file, so every Python process on the box, even pip, runs a stealer that ships your secrets to a fake litellm.dev and starts a daemon that can fetch and run more code.

What happened

LiteLLM is the Python SDK and proxy that sits between apps and dozens of LLM providers, so it tends to run with every provider key a company has. On October 21, 2026 a malicious litellm==1.107.0 landed on PyPI at 11:39 UTC, and the official Docker images under the v1.107.0, latest, main-latest and main-stable tags pointed at a poisoned build from 11:46 UTC. This is LiteLLM’s second release-pipeline compromise this year, after 1.82.7 and 1.82.8 in March. JFrog and Datadog say nothing links the two so far.

How it got out

According to LiteLLM’s own report, the attacker held GitHub CLI OAuth tokens belonging to three engineers. One belonged to an organization owner and was used to override branch protection on the private release workflow and point it at Berri-AI/litellm, a lookalike repo one hyphen away from the real BerriAI/litellm. A second token passed the production approval gate, and a third deleted the workflow run records afterwards. The real v1.107.0 git tag is clean. The artifacts were built from the attacker’s copy and signed by the real pipeline. LiteLLM suspects the tokens leaked through an internet-exposed internal deployment, possibly via a recently patched bug, but has not confirmed the initial access.

What the payload does

All seven 1.107.0 wheels carry three extra files: cook.pth, cook.py and sitecustomize.py. The source distribution does not. Because of the .pth hook, the stealer runs at every Python start in that environment, even if nothing imports LiteLLM and even when you run pip. Per Socket and JFrog it collects:

  • cloud credentials (AWS, Azure, GCP), instance-metadata tokens, and an STS GetCallerIdentity check
  • Kubernetes, Docker, Vault, Terraform and CI secrets; SSH, GPG and TLS keys; git, npm and PyPI configs
  • AI tool credentials (Claude, Codex, Gemini, Cursor, Copilot, Hugging Face and others)
  • browser databases, shell history, and every readable process environment on Linux
  • if DATABASE_URL is set, the LiteLLM proxy’s own LiteLLM_CredentialsTable and LiteLLM_ProxyModelTable, which hold your provider keys

The data is encrypted (AES-256 with an RSA-4096-wrapped key) and POSTed to www.litellm[.]dev/healthcheck. sitecustomize.py also forks a detached daemon that checks a GitHub dead drop every hour for a domain, then downloads and exec()s Python from it with no integrity check. The dead drop was empty when researchers looked and has since been removed, but the stealer part does not depend on it.

Is it being used?

Yes. Wiz observed stolen AWS instance-role credentials being validated from 168.100.8.57 and 165.227.201.8 roughly 4.5 hours after exfiltration, and IAM enumeration in “a small number” of environments. Datadog reports no second-stage payload seen in the wild. No source gives a download count for 1.107.0; the only figure cited is LiteLLM’s ~23 million weekly downloads overall, which is not the exposure.

Why L4

A package that by design holds every LLM provider key, a payload that steals cloud and AI credentials on any Python start, and confirmed attacker use of stolen credentials: that is active exploitation with mass credential theft. It stays below L5 because it was a single release live for about two hours, not self-propagating, and no core runtime or trust anchor broke.

What’s still unclear

  • Exact windows. LiteLLM says PyPI removal at 13:23 and Docker Hub cleaned by 14:20 UTC; Wiz and Datadog say 13:20 and ~13:53; the GitHub issue reported Docker tags still bad at 13:23 and yanked by 17:13. If you pulled a floating tag anywhere in that afternoon, check the digest.
  • Initial access to the engineers’ tokens is suspected, not confirmed.
  • No GHSA or CVE has been issued yet. Wiz tracks it as wiz-adv-2026-188, JFrog as XRAY-955589.
  • LiteLLM mentions an embargoed enterprise fix due for disclosure on October 27; it is not clear whether it is related.

Fixed versions

ProductSafe fromNote
LiteLLM (PyPI)1.106.2Last clean release; 1.107.0 removed
LiteLLM Docker imagesv1.106.2 (pin by digest)Floating tags were repointed
LiteLLM Enterprise (private registry)not affectedPer LiteLLM

Crime-scene timeline

  1. Oct 13, 2026

    Lookalike domain litellm.dev registered

    Per JFrog's WHOIS data.

  2. Oct 21, 2026, 08:56–10:46 UTC

    Payload committed to the lookalike repo Berri-AI/litellm

    Wiz counts 10 commits; the first three add cook.pth, cook.py and sitecustomize.py.

  3. Oct 21, 2026, 10:08 UTC

    Branch protection overridden on the private release workflow

    An org-owner's stolen GitHub CLI token disables protection and points the workflow at the lookalike repo.

  4. Oct 21, 2026, 11:11 UTC

    A second stolen credential approves the production release

  5. Oct 21, 2026, 11:39–11:40 UTC

    Seven malicious litellm 1.107.0 wheels uploaded to PyPI

    Socket's scanner flags them about seven minutes later.

  6. Oct 21, 2026, 11:46 UTC

    Malicious images published to GHCR and Docker Hub

    v1.107.0, latest, main-latest and main-stable all point at the same bad image index.

  7. Oct 21, 2026, 11:53 UTC

    A third stolen credential deletes the workflow run records

  8. Oct 21, 2026, ~13:20 UTC

    PyPI removes 1.107.0

    Wiz and Datadog say 13:20; LiteLLM's report says 13:23.

  9. Oct 21, 2026, 13:51–14:20 UTC

    Docker tags pulled or repointed to clean images

    GHCR first, Docker Hub by 14:20 per LiteLLM. Wiz and Datadog put removal at ~13:53.

  10. Oct 21, 2026, ~16:20–17:01 UTC

    Stolen AWS instance-role credentials used from attacker IPs

    Observed by Wiz in customer environments, about 4.5 hours after exfiltration.

Who said what

We list each claim and who made it. Primary sources (the vendor, the researcher, the registry) are marked. Where reports disagree, we grade by the worst credible case.

  • LiteLLM incident reportPrimaryThree engineers' GitHub CLI OAuth tokens used to bypass branch protection, approve and publish from Berri-AI/litellm; initial access suspected via an internet-exposed internal deployment (unconfirmed); 1.106.2 safe; enterprise unaffected
  • GitHub issue BerriAI/litellm#47826PrimaryReporter's analysis; all 7 wheels affected, payload not in the v1.107.0 git tag; Docker tags yanked by 17:13 UTC
  • SocketFull payload breakdown, wheel and file hashes, image digests; flagged wheels ~7 min after publish
  • JFrog Security ResearchExfil to www.litellm[.]dev/healthcheck, hourly dead-drop loader; no evidence linking this to the March TeamPCP compromise
  • WizObserved stolen AWS role credentials validated from 168.100.8.57 and 165.227.201.8; PyPI quarantine at 13:20 UTC
  • Datadog Security LabsLive roughly two hours; no second-stage payload observed in the wild