Published
- 6 min read
By Allan D - Editor, AI Security Wire
LiteLLM 1.107.0: Backdoored PyPI Wheels and Docker Images Steal AI Keys
Incident Classification: Confirmed | Incident Type: Reported | Severity: Critical (our assessment) | Sector: AI / Software Development Infrastructure | Date of Activity: 13 to 21 October 2026 (release 21 October) | Documented by StepSecurity, Endor Labs and Socket: 21 October 2026
A backdoored LiteLLM release reached PyPI and Docker registries on October 21, 2026. All seven wheels of litellm 1.107.0 carried a credential stealer that fires every time Python starts, plus a loader built to fetch and run code from an attacker-controlled host every hour. StepSecurity’s history of the pointer file shows it emptied on October 20, Socket saw an empty response at 13:01 UTC, and none of the three reports describes second-stage code being delivered. PyPI had removed the release by 13:23 UTC, according to StepSecurity. Any machine that installed it in that window needs to be treated as breached.
Incident Summary
| Field | Detail |
|---|---|
| Affected software | litellm 1.107.0 on PyPI (seven wheels); Docker images tagged v1.107.0 plus floating tags |
| Attack vector | Release built from a lookalike source repository, Berri-AI/litellm, one hyphen away from the legitimate BerriAI/litellm |
| Payload | Credential stealer plus remote code loader (hourly poll of a GitHub pointer), run through Python startup hooks |
| Exposure window (PyPI) | 11:39 UTC to removal by 13:23 UTC, 21 October (StepSecurity) |
| Safe version cited | 1.106.2 (StepSecurity, Endor Labs; Upwind via Socket) |
| Attribution | None named by any source we reviewed |
| Root cause | Not established; BerriAI reportedly still investigating |
Timeline
All times UTC, 21 October 2026 unless stated. Source: StepSecurity, with Socket and Endor Labs agreeing on the PyPI upload time.
- 13 October: The attacker registers the lookalike domain
litellm[.]dev, and creates GitHub accountletters9813. - 18 to 20 October: A dead-drop repository,
pythonclient-test, is created and its pointer file emptied after testing. - 08:56 to 10:46: Ten commits land on the lookalike
Berri-AI/litellmrepository, stacked on top of the clean v1.107.0 tag. - 10:51 to 11:06: The release workflow runs and the infected Docker images are built.
- 11:39 to 11:40: litellm 1.107.0 is uploaded to PyPI.
- 11:48: Infected images are pushed and floating tags point to them.
- 12:06: The problem is reported in BerriAI/litellm issue #47826.
- By 13:23: PyPI removes 1.107.0 (StepSecurity; Endor Labs says only “quarantined” later the same day).
- 14:32: BerriAI confirms the infected Docker images were removed.
How the Malicious Build Was Produced
The clean v1.107.0 git tag does not contain the payload. Endor Labs and StepSecurity both report that the malicious build came from other revisions: one commit added data = "cook" to the Maturin config along with a cook/ payload directory, and another added COPY cook ./cook to the Dockerfiles. The container’s SLSA provenance names Berri-AI as the source owner, which Socket and Endor Labs describe as a lookalike of the legitimate organization.
Two cautions. Provenance records build inputs, it does not prove they were trustworthy. And StepSecurity notes the attacker commits show GitHub’s “Verified” badge, which only indicates they were made through GitHub’s web editor. None of the three sources established how the build override was authorized or whether a token was stolen.
Payload Mechanics
The wheels install three files into site-packages: cook.pth, cook.py and sitecustomize.py. StepSecurity reports cook.pth is 12 bytes and contains import cook, so the stealer starts on every interpreter launch.
Stealer. Per StepSecurity, it collects browser passwords, cookies and history, SSH, GPG and TLS private keys, cloud, CI and developer credentials, .env files, instance metadata credentials (AWS, ECS, GCP, Azure), the environment of every readable process (on Linux), and tokens for a long list of named AI coding tools. If DATABASE_URL is set, it queries the LiteLLM proxy database for stored provider credentials and model configs. Endor Labs names the LiteLLM_CredentialsTable and LiteLLM_ProxyModelTable tables. The bundle is encrypted with AES-256-CBC, the key wrapped with RSA-4096 OAEP, and posted over plain HTTP to hxxp://www[.]litellm[.]dev/healthcheck.
Loader. sitecustomize.py forks into a detached daemon on Linux and macOS and polls hourly. It reads a domain from a pointer file in the attacker’s GitHub repository, then fetches and executes code from /codepy on that host. Endor Labs notes there is no signature or hash check on the downloaded code. StepSecurity reports the pointer file was emptied on October 20 and the attacker’s account later deleted, and Socket saw an empty response at 13:01 UTC. An empty pointer stops the loader reaching its download stage but not the separate stealer. Neither vendor can see what happened before they looked, so this does not prove no host received code. StepSecurity also warns that because the letters9813 account is deleted, anyone who re-registered that name and recreated the repository could arm the loader on infected hosts. On Windows the loader fails silently, while the stealer still runs.
The stealer’s marker file is only written after the server returns HTTP 200, so until then it reruns on every start.
Indicators of Compromise
Defanged. Hashes are SHA-256 from StepSecurity.
- Package and images:
litellm==1.107.0;ghcr.io/berriai/litellm:v1.107.0,ghcr.io/berriai/litellm-database:v1.107.0,ghcr.io/berriai/litellm-non_root:v1.107.0,docker.io/litellm/litellm:v1.107.0, and thelatest,main-latest,main-stabletags ofghcr.io/berriai/litellmon the day. - Files:
cook.pth,cook.py,sitecustomize.pyin site-packages;/tmp/remote_code_loader.lock;/tmp/.pc_once_72129118c59f5636c0bb. - Network:
litellm[.]dev; theletters9813/pythonclient-testdead-drop path on raw.githubusercontent.com; any request path ending/codepy. - Environment variable:
PRIVCOLLECT_ACTIVE=1. - Hashes:
cook.pth7f191632e7320705d154b85204f1ae546b543acbd7e8861229b76f5042b92bdb;cook.py9dd0a3926f96a37eb86cf1ee2310d9be93139cc4ebef3ef9e2efe9531390be25;sitecustomize.py34bef04fe88ac9d0aae0475630b1738681d15b94f233ac8aa46eacf5968305fa.
Remediation and Response
- Do not start Python or pip in an affected environment first. Each launch re-runs the collector (Endor Labs, Socket).
- Isolate the host. Kill any process holding
/tmp/remote_code_loader.lock. - Remove the payload files and their
__pycache__entries, then redeploy rather than cleaning in place where possible. For containers, rebuild on a pinned digest. - Pin a pre-compromise version. StepSecurity and Endor Labs cite 1.106.2. Socket attributes that recommendation to Upwind and does not independently certify it.
- Purge mirrors and caches of 1.107.0. StepSecurity’s report lists the per-wheel and Windows-variant hashes, which this article does not reproduce.
- Rotate every credential the host could reach, from a clean machine. On proxy hosts, rotate all upstream provider keys, the master key and the salt key.
- Hunt. Search egress logs for
litellm[.]devand the dead-drop path. A request to/codepymeans attacker code executed, so widen scope. Do not treat a missing marker file as an all-clear: Socket notes failed uploads or container replacement can leave none. Endor Labs warns against blocking raw.githubusercontent.com wholesale.
What This Means
LiteLLM sits where AI infrastructure keeps its most valuable secrets: it holds keys for several model providers in one place. That makes the proxy host a better target than most Python packages. The same project was hit in March 2026 in a separate incident that we covered in our TeamPCP report, and nothing in the three reports we reviewed, as of October 22, 2026, ties this release to that group.
Three design lessons stand out. Floating Docker tags turned a short-lived publish into a three-hour exposure. Open-ended litellm>= constraints let any resolution in the window pull the bad version. And .pth and sitecustomize hooks mean the first sign of trouble may be an unrelated Python command. Pin by hash or digest, restrict who can run builds that publish, and verify that a release’s provenance names the repository you expect.
References
Frequently Asked Questions
- Do I need to have imported LiteLLM to be affected by version 1.107.0?
- No. According to StepSecurity, Endor Labs and Socket, the payload installs cook.pth, cook.py and sitecustomize.py into site-packages, and Python executes them on every interpreter start. Any Python or pip process in an environment where the malicious wheel was installed could trigger the stealer, whether or not LiteLLM was ever imported.
- Which LiteLLM artifacts were malicious and which were clean?
- StepSecurity reports that all seven 1.107.0 wheels and the 1.107.0 Docker images carried the payload, including the floating tags latest, main-latest and main-stable for about three hours. The 1.107.0 source distribution was tampered with but omitted the payload files. StepSecurity lists 1.107.0rc1, 1.107.0rc2 and 1.106.x back to 1.103.x wheels as clean, and did not inspect the 1.107.0.dev1 to dev3 pre-releases. Socket notes it did not independently certify earlier artifacts.
- What should I rotate if a host ran the malicious package?
- Treat the host as compromised. The vendor reports list cloud keys and instance roles, SSH, GPG and TLS keys, browser-saved passwords and sessions, registry tokens for GitHub, npm and PyPI, Kubernetes and Vault tokens, CI secrets and AI coding tool tokens. On LiteLLM proxy hosts with DATABASE_URL set, also rotate every upstream provider key stored in the proxy database, plus the master key (named by StepSecurity and Endor Labs) and salt key (named by StepSecurity). Do the rotation from a clean machine.
- Has anyone been attributed for the LiteLLM 1.107.0 compromise?
- No source we reviewed attributes the release. We found no attribution as of October 22, 2026 in the StepSecurity, Endor Labs and Socket reports. How the lookalike build source came to publish the release is also unexplained: Endor Labs and Socket say the available evidence does not establish how the override was authorized, and StepSecurity says BerriAI was still investigating.