On 21 October 2026, LiteLLM 1.107.0 was published to PyPI and to the project’s Docker image tags with a credential stealer inside. LiteLLM says its own release pipeline was compromised. If 1.107.0 ever ran in your environment, treat every secret that host could read as stolen. LiteLLM says all earlier versions are safe, and PyPI has removed 1.107.0.
This post covers what the sources say, where they disagree, and a checklist you can work through today. The full record sits in our LiteLLM 1.107.0 incident profile.
What Happened to LiteLLM on 21 October?
LiteLLM’s own incident post says version 1.107.0 contained compiled malware that steals credentials and loads remote code tools. Seven wheels, covering Linux, macOS and Windows, went to PyPI between 11:39:51 and 11:40:13 UTC.
The affected Docker tags were v1.107.0, latest, main-latest and main-stable. LiteLLM also says the official v1.107.0 source tag on GitHub does not contain the malicious files, and that its enterprise private release was not affected. On 24 October its security lead wrote on GitHub issue 47826 that there is in fact no official v1.107.0 source tag.
This is the second LiteLLM supply chain incident this year. In March 2026, two other versions were published with a stealer, as covered in our LiteLLM PyPI package compromise profile and the Trivy pipeline lessons post. The October release took a different route, described below.
How Did the Bad Release Get Built?
LiteLLM says three engineers’ GitHub accounts were used, through stolen GitHub CLI OAuth tokens. One account changed the private release workflow and triggered the run. A second approved the production step. A third deleted workflow records.
LiteLLM’s analysis of 23 October explains how the attacker got the tokens.
The master key of its experimental Agent Platform was committed to the public LiteLLM-Labs/lite-harness repository on 27 May 2026. The commit was force-pushed over, but the key was never revoked. On 10 October the attacker used it to read a GitHub organization owner’s GitHub CLI token. Throwaway CI workflows then took the tokens of two more maintainers.
LiteLLM says the GH_TOKEN secret taken by the 10 October workflow is the token that approved the production release on 21 October. It also replaces LiteLLM’s first theory that the tokens came from the logs of an internal deployment.
Socket reports that workflows built to collect the project’s CI secrets ran in the BerriAI/litellm GitHub repository from at least 10 October, eleven days before the bad release. Two commits added a workflow file named cache.yml on short-lived ci-tmp branches that were created, used and deleted within minutes.
Across the two workflows, 20 distinct secret names were referenced, and the results were posted to webhook.site collectors.
Socket says it has not established how the attacker got access. It cannot confirm that the collectors received the data. It does not claim the 10 October theft produced the access used on 21 October. LiteLLM’s analysis, above, answers that question.
Socket and Wiz add that the staging build ran from a lookalike repository, Berri-AI/litellm, one hyphen away from the real BerriAI/litellm. SafeDep adds that a build setting added a folder named cook to the wheels but not to the source archive. SafeDep rates as moderate to high confidence that the wheels came from attacker-modified source built by the project’s own pipeline. That is an assessment, not a confirmed finding.
- Key leaked, tokens stolenA master key committed to a public repository on 27 May was never revoked, and on 10 October it returned an organization owner’s GitHub token
- Release workflow changedLiteLLM says a developer credential overrode branch protection on the private release workflow
- Build from a lookalike repoThe staging build ran from Berri-AI/litellm, not BerriAI/litellmTechnique T1195.001 (MITRE ATT&CK, opens in a new tab)
- Bad release publishedSeven wheels to PyPI and a Docker image with four tags
- Python start hookcook.pth imports the stealer every time Python startsTechnique T1546.018 (MITRE ATT&CK, opens in a new tab)
- Secret theftCloud, developer, CI and AI tool credential files and environment variables are readTechnique T1552.001 (MITRE ATT&CK, opens in a new tab)
- Upload and loaderAn encrypted bundle goes to litellm[.]dev, and a background loader polls a dead drop for more code
The steps above merge what LiteLLM, Socket, SafeDep and Wiz each describe. The MITRE ids are Socket’s mapping. Our related Compromise Software Supply Chain page covers the wider technique.
What Does the Malware Do?
The wheels install three files into site-packages: cook.pth, cook.py and sitecustomize.py. The .pth file runs at every Python start, so the stealer runs even in programs that never import litellm. That is the technique MITRE calls Python Startup Hooks. Socket warns that sitecustomize.py can be a legitimate file, so the name alone is not proof.
Per Socket, the stealer reads cloud and deployment credentials for AWS, Azure, Google Cloud, Kubernetes, Docker, GitHub CLI, Vault and Terraform. It also reads Git, npm and PyPI config, .env files, SSH, GPG and TLS keys, AI tool credential files, browser data and shell histories. When a database URL is set, it queries the LiteLLM proxy tables that hold provider keys. That matches MITRE’s Credentials in Files.
The data is encrypted and posted to www.litellm[.]dev/healthcheck. The sitecustomize.py file starts a detached loader that reads a domain from a GitHub dead-drop file and runs code fetched from that domain every hour. StepSecurity says the loader fails silently on Windows, while the stealer still runs. Wiz reports that the dead-drop file was never populated beyond test values, and SafeDep says the account hosting it was later deleted.
Microsoft adds detail on how the stealer works. The cook.pth file has a single executable line, import cook, which loads cook.py. That file decodes an embedded collector and runs it in a background thread.
Microsoft says the collector works through its modules one after another, each with its own error handling. Microsoft adds that it reads:
- Kubernetes service account files, Docker config and mounted secrets.
- On Linux, the environment of other processes it is allowed to see.
- On the proxy, selected fields from two database tables, up to 500 rows per query.
The collector also tries to get credentials from the AWS and Google Cloud metadata services. Microsoft says it saw a routine Python command that installed an unrelated dependency on Windows start the collector.
The bundle is encrypted with AES-256-CBC, the key is wrapped with an embedded 4,096-bit RSA public key, and the upload goes to the /healthcheck address named above.
Microsoft says the dead-drop file was empty when the researchers it cites examined it. Microsoft adds that no second-stage retrieval or execution was confirmed, including on the Unix loader path. It says the loader could be armed again later.
Which Times Do the Sources Agree On?
LiteLLM gives the most detailed times, and we use them here. Others differ in small ways. Wiz writes that PyPI quarantined the release “as of 1:20 UTC”. That is before the 11:39 upload, so it most likely means 13:20 UTC.
Wiz also says the images were gone around 13:53 UTC. StepSecurity says BerriAI confirmed the images removed at 14:32 UTC. Socket dates the first build run at 10:51 UTC, while LiteLLM dates its staging build at 10:46 UTC.
- 10:46Staging build runs from the lookalike repositoryLiteLLM
- 11:39Seven wheels uploaded to PyPI, finished 11:40:13LiteLLM
- 11:46Container publish jobs run, image contains malwareLiteLLM
- 13:23PyPI removes litellm 1.107.0LiteLLM
- 13:51Affected GHCR tags unavailableLiteLLM
- 14:20Docker Hub tags removed or repointed to clean artifactsLiteLLM
Dates before 21 October agree. LiteLLM says the attacker called the Agent Platform API between 21:13 and 21:28 UTC on 10 October, and the call that returned the owner’s token came at 21:27. LiteLLM and Socket both put the first secret-collecting workflow at 22:11 UTC that day. Socket dates a second one to 12 October.
What Should You Do Now?
Work from LiteLLM’s guidance, with Socket and StepSecurity for detail. The order below follows StepSecurity, which stops the loader before deleting the files. The order matters: do not run pip install in a suspect environment first, because Python startup re-runs the malicious files.
- Find the exposureSearch lockfiles, caches, build logs and running containers for litellm 1.107.0 and for the affected image digest.
- Look for the filesCheck site-packages for litellm-1.107.0.dist-info, cook.pth, cook.py and sitecustomize.py. Finding none does not prove a clean host.
- Stop the loaderEnd the process holding /tmp/remote_code_loader.lock, then delete the three files and matching cached bytecode.
- Rebuild from a clean imagePin litellm 1.106.5, which also fixes the flaw in the 27 October advisory, or the clean image by digest. Rebuild images and virtual environments from scratch.
- Rotate every secret the host could readCloud and instance role keys, SSH and GPG keys, CI and registry tokens, AI tool tokens and database passwords.
- Rotate the proxy’s keysOn a LiteLLM proxy, rotate all provider keys in the database, plus master and virtual keys.
- Check the network and cloud logsSearch for litellm[.]dev, its /healthcheck path and any /codepy request, and for GetCallerIdentity calls from the instance role.
- Revoke keys that were ever publicRun secret scanning over your repositories and their history, and revoke every key or token that was exposed, even if the commit was rewritten. Give automation narrow tokens, not an owner’s.
A /codepy request means second-stage code ran, and the scope of the incident is larger. Block litellm[.]dev at DNS or egress and alert on the dead-drop address. Wiz reports that about 4.5 hours after exfiltration the attacker tested stolen AWS instance role credentials and listed Bedrock models, which Wiz calls consistent with LLMjacking. Check your cloud audit log for that pattern, and see our guide on how to respond to leaked credentials.
Microsoft stresses that removing the package or the release tag is not a recovery. Look for copies in:
- installed environments
- uv and pip caches
- internal mirrors
- lock files
- build outputs
- container images
Compare what you find with the file hashes in Microsoft’s post. Do not run Python or pip in a suspect environment; inspect it from a clean system. Rebuild from verified artifacts and confirm that the three startup files are gone from the library path.
Rotate secrets from a clean machine and also revoke sessions, because rotating a credential may not end a token that is already active.
Microsoft maps the case to ATT&CK techniques that include T1546.018, T1195.001, T1102.001 (dead drop resolver) and T1105 (ingress tool transfer). It says it has not independently determined how the attacker first got access or the developer credentials. LiteLLM’s root cause analysis covers that, as the update at the top says.
For detection, Microsoft Defender lists antivirus signatures named:
Trojan:PyPI/Stealer.SATrojan:PyPI/LiteLlmSupplyChain.ATrojan:PyPI/LiteLlmSupplyChain.BBackdoor:PyPI/LiteLlmSupplyChain.C
Microsoft’s post also has advanced hunting queries for connections to litellm[.]dev, the known startup file hashes and OpenSSL commands that use .pc_e_ staging folders. Microsoft calls these queries leads, not verdicts, so confirm a hit with process, network and identity logs.
What Do Public Posts and Underground Channels Show?
We counted public posts on X mentioning LiteLLM on 21 October 2026. The 169 newest unique posts, written between 15:52 and 20:04 UTC, are mostly in English (121), with 19 in Chinese.
Volume peaked at 19:00 UTC. Nine of the posts appear to share indicators. The outside page linked most often is SafeDep’s write-up, with 11 links.
In the underground chat and forum sources we monitor we found 60 posts that mention LiteLLM between 21 September and 21 October 2026, 57 of them on Telegram. 24 are dated 21 October. We cannot tell from counts who read the stolen data or what was done with it. Keys that leave a company can later appear in stealer logs or for sale, which is the kind of exposure our leaked credential monitoring page describes.
What Should Teams Change After This?
Four points stand out in LiteLLM’s account of the incident.
- Branch protection that one privileged credential can override is not a control against stolen tokens.
- Approval by a second credential is weaker than it looks if both tokens can be stolen.
- A clean source repository does not make the package clean, so compare what you install with the source it claims to come from.
- A key that was exposed once stays dangerous until it is revoked. LiteLLM says the master key was committed in May and the commit was force-pushed over, but the key was never revoked, so it still worked on 10 October. The token it opened belonged to an organization owner, not a scoped service account.
For your own pipelines, pin dependencies and image digests, and keep release credentials apart from dependency installs and tests. Socket’s finding also shows that a workflow pushed and deleted on a short-lived branch leaves little behind. Review the Actions run history and the organization audit log, not only the workflow files on the default branch. Today, search your lockfiles and run the checklist above.
For the wider picture, read our supply chain attack and malicious package entries. Our earlier analysis of AI gateway exploitation explains why model provider keys on gateways are a target.
Railway said on 21 October that an incident on its own platform looks like part of a series of attacks aimed at AI inference providers. Our Railway rotation checklist covers what its users should change. Microsoft has since tied a China state-aligned actor to a different vendor compromise. Read our note on the ConnectWise supply chain attack and the ARTEX framework.
Frequently Asked Questions
Which LiteLLM version was compromised?
Only litellm 1.107.0, in all seven PyPI wheels, plus the Docker tags v1.107.0, latest, main-latest and main-stable. SafeDep lists 1.106.2, 1.107.0rc1 and 1.107.0rc2 as clean.
Which versions are safe?
LiteLLM names litellm 1.106.2, or any explicit version published before the incident. StepSecurity names 1.106.4 and the backports 1.105.5, 1.104.7 and 1.103.9 as clean. Socket notes that it did not certify every earlier artifact. LiteLLM's 27 October advisory GHSA-w4c7-34wj-hqm8 adds a critical flaw for Enterprise proxies before 1.106.5 (1.103.10, 1.104.8 and 1.105.6 on older lines).
Was I affected if I never imported litellm?
Possibly. SafeDep says the .pth file runs when any Python process starts on the host, even one that never imports litellm.
What should I rotate?
LiteLLM lists the instance or task role, all provider keys in the proxy database, master and virtual keys, the database password and any secret in process environments. Add SSH, CI and AI tool tokens from the same hosts.
Who is behind the attack?
LiteLLM's own post names no actor, and no source cited in this post links the October release to a named group.
Is there a CVE for this?
No CVE id or GitHub advisory number is cited for it in the sources listed on this page.
How did the attacker get the tokens for the LiteLLM 1.107.0 release?
LiteLLM says the master key of its experimental Agent Platform was committed to a public repository on 27 May 2026 and never revoked. The attacker used it on 10 October to read an organization owner's GitHub token. With that token, the attacker took two maintainers' tokens from CI secrets. On 21 October the owner's token changed the release workflow and started the build, one maintainer's token approved the production release and the other deleted the run records.
Sources
- LiteLLM, Contained: Oct 21, 2026 LiteLLM release v1.107.0 Compromised
- LiteLLM, The attack chain behind the v1.107.0 LiteLLM release
- BerriAI/litellm on GitHub, Issue 47826
- Python Package Index, litellm project page and release history
- Microsoft Security, Inside the LiteLLM 1.107.0 supply chain compromise: Credential theft through Python startup hooks
- Socket, LiteLLM PyPI Package and Docker Images Compromised to Steal Cloud and AI Credentials
- Socket: New Evidence Shows LiteLLM Secret-Stealing Workflows Ran 11 Days Before Supply Chain Attack
- Wiz, LiteLLM Compromised, Steals Credentials
