---
title: "LiteLLM 1.107.0: Malicious PyPI and Docker Release"
url: https://erroneo.us/security/briefs/litellm-1-107-0-supply-chain-compromise/
description: "litellm 1.107.0 on PyPI and Docker (Oct 21, ~2h) shipped a credential stealer that runs on any Python start. If it ran: isolate, rebuild, rotate all."
type: security-brief
section: "Security Digest"
date_published: 2026-10-21
date_modified: 2026-10-21
publisher: erroneo.us
author: erroneo.us Security Desk
verdict: "Act now"
cves: []
severity: "critical"
exploited: "in-the-wild"
kev: false
license: All rights reserved. Quote with attribution and a link.
---

# LiteLLM 1.107.0: Malicious PyPI and Docker Release

**Verdict: Act now.** Check right now whether anything installed litellm 1.107.0 or pulled a LiteLLM image by a floating tag on October 21; if it did, assume every secret that host could read is stolen.

- **Who must act:** Anyone whose laptops, CI runners, containers or Kubernetes nodes resolved litellm (unpinned or >=) or a latest/main-* LiteLLM image between about 11:39 and 14:20 UTC on October 21, 2026.
- **Who can relax:** Teams pinned to 1.106.2 or earlier by hash/lockfile, image users pinned by digest to a pre-incident image, and LiteLLM Enterprise private-registry customers, which LiteLLM says were not affected.
- **Affected:** PyPI litellm==1.107.0 (all seven wheels), 11:39:51 to ~13:23 UTC Oct 21, 2026; ghcr.io/berriai/litellm, litellm-database, litellm-non_root tags v1.107.0, latest, main-latest, main-stable from 11:46:56 UTC; docker.io/litellm/litellm same tags until 14:20 UTC (index sha256:1bbcb1443bc962e45f5aad53fe3d2c30600e0379715fb6c664cdd3ac126c339e)
- **Fixed:** litellm==1.106.2 (last known-good); Malicious 1.107.0 quarantined on PyPI and tags removed from registries
- **CVEs:** none
- **CISA KEV:** no · **Exploitation:** Exploited in the wild

## What to do

1. Find exposure: pip show litellm, grep lockfiles and CI logs for 1.107.0, and list running image digests.
2. On any hit, isolate the host or container and preserve evidence; do not run that environment's python or pip first.
3. Kill the detached daemon holding /tmp/remote_code_loader.lock and delete cook.pth, cook.py, sitecustomize.py (and their .pyc) from site-packages, or better, destroy and rebuild the environment.
4. Reinstall pinned to litellm==1.106.2 with hashes, and pin images by digest.
5. From a clean machine, rotate everything the host could reach: cloud role/keys, every provider key in the LiteLLM DB plus master/virtual keys, DATABASE_URL, GitHub/npm/PyPI tokens, SSH/GPG keys, AI-tool sessions.
6. Review CloudTrail/cloud audit logs for sts:GetCallerIdentity and Bedrock ListFoundationModels from unfamiliar IPs, including 168.100.8.57 and 165.227.201.8.

### How to check if you are affected

- pip show litellm (any environment) and pip download caches; look for litellm-1.107.0.dist-info.
- find / -name cook.pth -o -name 'sitecustomize.py' -path '*site-packages*' 2>/dev/null; check for /tmp/.pc_once_72129118c59f5636c0bb and /tmp/remote_code_loader.lock.
- docker images --digests | grep litellm and kubectl get pods -o jsonpath for image IDs; compare to sha256:1bbcb144... and the per-variant indexes.
- Egress/DNS logs for www.litellm.dev/healthcheck, raw.githubusercontent.com/letters9813/pythonclient-test, or requests with header X-Token: XWiA8gZNa7NcX2XRoAEb.

## What happened

On October 21, 2026, an attacker published `litellm==1.107.0` to PyPI and pushed matching container images. LiteLLM is a widely used Python SDK and proxy that fronts dozens of LLM providers, and [Datadog](https://securitylabs.datadoghq.com/articles/litellm-compromised-pypi-docker/) cites about 23 million weekly downloads. According to [LiteLLM's incident report](https://docs.litellm.ai/blog/security-incident-oct-21-2026), all seven 1.107.0 wheels were live from 11:39:51 UTC to about 13:23 UTC. On Docker Hub and GHCR, the tags `v1.107.0`, `latest`, `main-latest` and `main-stable` pointed to malicious image indexes from 11:46:56 UTC. They were withdrawn from GHCR by 13:51 and from Docker Hub by 14:20. The official GitHub `v1.107.0` source tag is clean. The artifacts were built from a lookalike repository, `Berri-AI/litellm` (one hyphen), rather than `BerriAI/litellm`.

LiteLLM's current understanding is that stolen GitHub CLI OAuth tokens belonging to three engineers were used for four steps: altering a release workflow, overriding branch protection, satisfying a production approval gate, and deleting workflow records afterward. It suspects, but has not confirmed, that the initial access came through an internally exposed LiteLLM deployment. LiteLLM says the private Enterprise release and registry were not affected.

## Who is affected

You are affected if any machine installed 1.107.0 or ran one of the affected image digests. That includes unpinned `pip install litellm` in CI, a `litellm>=` constraint that resolved that morning, or a Kubernetes deployment that pulled `:latest` or `:main-stable`. Each wheel drops three files into `site-packages`, as [Socket](https://socket.dev/blog/litellm-compromise) and Datadog both document:

- `cook.pth`. Python runs `.pth` files at every interpreter start, so the stealer fires even if your code never imports LiteLLM. It fires when you run `pip`, too.
- `cook.py`, the credential stealer. It targets AWS, GCP and Azure credentials (including instance metadata), Kubernetes, Vault and Terraform secrets, SSH, GPG and TLS keys, Git, npm and PyPI tokens, `.env` files, browser cookies and passwords, and AI-tool sessions such as `~/.claude/.credentials.json` and `~/.codex/auth.json`. If `DATABASE_URL` is set, it also reads the LiteLLM proxy's stored provider credentials.
- `sitecustomize.py`, a loader on Linux and macOS that polls a GitHub dead drop every hour and would `exec` second-stage Python from it. Researchers saw no second stage served before GitHub removed the repository.

## Do you really need to act?

**Everyone needs to check. Only those who ran it need to respond.** The window was about two hours, but CI pipelines and floating container tags are built to pull new releases quickly. Theft is not hypothetical. [Wiz](https://wiz.io/blog/litellm-compromised-steals-credentials) observed stolen AWS instance-role credentials from CI runners and Kubernetes nodes being validated from `168.100.8[.]57` and `165.227.201[.]8` roughly three to five hours after the release. The attackers called `sts:GetCallerIdentity` and then Bedrock model listing, which fits LLMjacking. If the affected host had outbound internet access, LiteLLM says to assume exfiltration succeeded. Uninstalling the package does not remove the startup files. Exfiltration is encrypted with an embedded RSA-4096 key, so you cannot tell what was taken. If you pin by lockfile hash or image digest and did not bump anything on October 21, you can relax.

## What to do now

1. **Find it.** Run `pip show litellm` in every virtualenv and image, `grep -r "litellm.*1.107.0" poetry.lock uv.lock requirements*.txt`, search CI logs, and run `docker images --digests | grep litellm`. Compare against index `sha256:1bbcb1443bc9…c339e` and the per-variant indexes in the LiteLLM report.
2. **Isolate before touching.** Do not run the affected environment's `python` or `pip`, because that re-triggers the payload. Preserve disk and memory if you can.
3. **Clean or, better, rebuild.** Kill the detached process holding `/tmp/remote_code_loader.lock`. Delete `cook.pth`, `cook.py`, `sitecustomize.py` and their `__pycache__` files from every site-packages directory. Then destroy the venv or image and rebuild it pinned to `litellm==1.106.2`.
4. **Rotate from a clean machine.** Cover the instance or task IAM role and any static cloud keys, every provider key in the proxy DB plus master and virtual keys, the `DATABASE_URL` password, GitHub, npm and PyPI tokens, SSH and GPG keys, and logged-in AI-tool and browser sessions.
5. **Hunt in the cloud.** Review CloudTrail and your other providers' audit logs from 11:39 UTC onward for role use outside your network.
6. **Harden.** Install with `pip install --require-hashes` or a uv or poetry lockfile, reference images by `@sha256:` digest rather than by tag, and consider a release-age cooldown before adopting new versions.

## How to tell if you were hit

Artifacts that confirm execution:

- `litellm-1.107.0.dist-info` or `cook.pth` in site-packages.
- The upload marker `/tmp/.pc_once_72129118c59f5636c0bb`.
- The environment variable `PRIVCOLLECT_ACTIVE=1` in a process.
- Egress to `www.litellm[.]dev/healthcheck` carrying the header `X-Token: XWiA8gZNa7NcX2XRoAEb`.
- Requests to `raw.githubusercontent.com/letters9813/pythonclient-test`.

Wiz and Socket also publish wheel and payload SHA-256 hashes. Missing artifacts do not prove a host is clean, because the marker path fails on Windows and an attacker or reinstall can remove files.

## Timeline

- Oct 21, 2026 — 08:56–10:46 UTC: the attacker pushes commits to `Berri-AI/litellm`, and a workflow change at 10:08 overrides branch protection.
- Oct 21, 2026 — 11:39:51 UTC: 1.107.0 is on PyPI. Malicious images are tagged from 11:46:56.
- Oct 21, 2026 — Around 13:20–13:23 UTC PyPI quarantines the release. GHCR tags are gone by 13:51 and Docker Hub tags by 14:20.
- Oct 21, 2026 — Around 16:20–17:01 UTC Wiz observes stolen AWS role credentials being validated. LiteLLM declares the incident contained, with the investigation ongoing.

## Sources

1. [LiteLLM — Security incident, October 21, 2026](https://docs.litellm.ai/blog/security-incident-oct-21-2026)
2. [Datadog Security Labs — LiteLLM supply chain compromise: What you need to know](https://securitylabs.datadoghq.com/articles/litellm-compromised-pypi-docker/)
3. [Wiz — LiteLLM Compromised, Steals Credentials](https://wiz.io/blog/litellm-compromised-steals-credentials)
4. [Socket — LiteLLM PyPI package and Docker images compromised](https://socket.dev/blog/litellm-compromise)

---
Source page: https://erroneo.us/security/briefs/litellm-1-107-0-supply-chain-compromise/ · Security Digest: https://erroneo.us/security/ · More: https://erroneo.us/llms.txt
