The LiteLLM PyPI Supply Chain Attack
Updated 5 Oct 2026 · Incident date 24 Mar 2026 · PyPI
litellm 1.82.6 -> 1.82.7 and 1.82.8litellm/proxy/proxy_server.pyLiteLLM versions 1.82.7 and 1.82.8 on PyPI were malicious. The group TeamPCP published both on 24 March 2026. They hold a three-stage credential stealer that collects SSH keys, cloud credentials and Kubernetes tokens, and then installs a persistent backdoor. Version 1.82.6 is the last clean release, according to BleepingComputer.
The attack followed the Trivy compromise five days earlier, see the Trivy attack page. This page explains how the attackers got the publishing token, what the malware took, and how to check a machine. A plain uninstall does not remove the backdoor.
What LiteLLM is and why it was a target
LiteLLM is an open-source library that routes requests across large language model providers through one API. Endor Labs reports that the library receives more than 95 million downloads a month on PyPI. Teams run it as a gateway, so it often sits next to the keys for many AI providers and for cloud accounts.
That position makes it a good target. A gateway process holds API keys for several vendors. The server that runs it often holds cloud credentials and Kubernetes access too. One poisoned release reaches all of them. Environments that install the latest version on each build received the bad code with no action from the owner.
The attackers did not break into LiteLLM by guessing a password. They used a secret that an earlier attack had exposed. The next section gives the chain.
How the publishing token was stolen
The attackers took the PyPI publishing token from LiteLLM's own build pipeline through the poisoned Trivy action. Snyk reports that LiteLLM's CI ran Trivy without a pinned version. On 19 March 2026 the Trivy GitHub Action tags were rewritten to point at a malicious release. When LiteLLM's pipeline ran the action, the code pulled the PYPI_PUBLISH token from the runner environment.
With that token the attackers published to PyPI directly. No change went through the LiteLLM GitHub repository. Endor Labs confirms that the malicious code was absent from the GitHub source. A reviewer who read the repository saw nothing wrong.
| Time (UTC) | Event |
|---|---|
| 19 Mar, 17:43 | Malicious Trivy release and tag changes go out. |
| 23 Mar, 12:58 | The domains checkmarx.zone and models.litellm.cloud are registered. |
| 24 Mar, 10:39 | litellm 1.82.7 is published. |
| 24 Mar, 10:52 | litellm 1.82.8 is published, 13 minutes later, with a stronger trigger. |
| 24 Mar, about 13:38 | PyPI quarantines the packages after about three hours. |
For the full Trivy side of the chain, read The Trivy Supply Chain Attack.
What the malware took
The malware took credentials of every kind it found, sent them out encrypted, and then set itself up to stay. It ran in three stages. JFrog, Snyk and Endor Labs describe the same stages.
How it started. The two versions used different triggers.
- Version 1.82.7 added about 12 lines to
litellm/proxy/proxy_server.py. They hold a base64 blob that Python decodes and runs when the module is imported. - Version 1.82.8 kept that code and added a new file,
litellm_init.pth, insite-packages. Python runs.pthfiles at every start. The payload therefore ran whenever Python ran, even if the program never used LiteLLM.
Stage 1 and 2: collect and send. The code collected SSH keys and configuration, AWS, GCP and Azure credentials, Kubernetes secrets and tokens, Docker credentials, .env files, database credentials, TLS private keys, CI secrets, shell history and cryptocurrency wallets. It encrypted the data with AES-256-CBC and wrapped the key with a 4096-bit RSA key. It sent the archive, named tpcp.tar.gz, by HTTPS POST to models.litellm.cloud. If the host had Kubernetes access, the harvester tried to deploy privileged pods to the cluster nodes.
Stage 3: stay. The code wrote a backdoor to ~/.config/sysmon/sysmon.py and registered it as a systemd user service. The backdoor polled checkmarx.zone/raw every 50 minutes for more payloads.
BleepingComputer reports about 500,000 data exfiltrations. The same report says the attackers used the domain checkmarx.zone in the Checkmarx KICS and Trivy attacks too. The two poisoned releases changed files in two ways: a decoded-and-executed blob in proxy_server.py and a new .pth file.
How to check if you were affected
Check the installed version of litellm, then check for the backdoor files. Treat any machine that ever had 1.82.7 or 1.82.8 as compromised, even for a short time. These commands only read data.
pip show litellm pip freeze | grep litellm find / -name litellm_init.pth 2>/dev/null
If the version is 1.82.7 or 1.82.8, or the .pth file exists, the host ran the malware. Run the next check for the backdoor.
ls -l ~/.config/sysmon/sysmon.py ~/.config/systemd/user/sysmon.service /tmp/pglog /tmp/.pg_state systemctl --user status sysmon.service
Check the package caches too. JFrog lists ~/.cache/pip/, ~/.cache/uv/ and the site-packages folder. A cached bad wheel can come back at the next install. Look in Docker image layers and build artifacts made on 24 March 2026.
If you use Kubernetes, look for pods named node-setup-<node name> in the kube-system namespace.
kubectl get pods -n kube-system | grep node-setup
Search DNS and proxy logs for models.litellm.cloud and checkmarx.zone. The SHA-256 of litellm_init.pth is 71e35aef03099cd1f2d6446734273025a163597de93912df321ef118bf135238, per Snyk.
Is uninstalling enough?
No. Uninstalling litellm does not remove the backdoor, the Kubernetes pods or the stolen credentials. JFrog states that the malware sets up systemd persistence, deploys pods in kube-system and stores downloaded binaries in /tmp. Removing the package leaves all three in place.
If you found the bad versions, do these steps in order.
- Stop and remove the persistence:
systemctl --user stop sysmon.service,systemctl --user disable sysmon.service, then delete~/.config/sysmon/sysmon.py,~/.config/systemd/user/sysmon.service,/tmp/pglogand/tmp/.pg_state. - Delete any
node-setup-*pods inkube-system. - Move to litellm 1.82.6 or earlier, as Snyk advises. Clear the pip and uv caches.
- Rotate every credential the host can read: SSH keys, cloud keys, LLM API keys, Docker and Kubernetes credentials and database passwords. Audit AWS Secrets Manager and Parameter Store, as Snyk advises.
- Block
models.litellm.cloudandcheckmarx.zoneat the firewall or DNS.
JFrog says to assume total credential compromise. The malware had every secret on the host, so a rotated list that is shorter than the real list leaves a way in.
How to stop the next PyPI attack
You can reduce the risk by pinning what you install and by limiting what a build job can read. These steps come from the incident reports on LiteLLM and Trivy. They do not need a new tool.
- Pin build tools by commit SHA. LiteLLM's token left through an unpinned Trivy action. Microsoft and Snyk both advise SHA pins for GitHub Actions. See the Trivy page for the safe versions.
- Pin Python packages. Use exact versions in a lock file, not
litellmwith no version. A pinned install of 1.82.6 does not take 1.82.7. - Limit token scope. A token that can publish a package must not be readable by every step in a job. Microsoft advises minimal token scope and ephemeral runners.
- Watch outbound connections from CI and from servers that hold keys.
- Compare each update with the version you trust. Vigilance compares a new release with a version you already trust and reports the file that gained a new capability. For these releases it shows a decoded-and-executed blob in
proxy_server.pyand a new.pthfile that runs at every Python start. It is not a CVE scanner.
The same pattern of a stolen publisher credential hit npm one week later, see the axios attack.
What Vigilance showed
Vigilance compares the version you trust with the new one and names the file that gained a new capability. The block below is rebuilt from the public reports in the words Vigilance prints. It is not a captured scan, because the malicious release is not redistributed.
files scanned: 74 (1 Added) HEADS UP 1 file can now do things the old version could not. The rest changed and gained nothing. NEW FILE litellm/proxy/proxy_server.py It downloads from the internet, reads saved passwords and access keys and runs other programs.
Frequently asked questions
Is LiteLLM safe to use now?
Version 1.82.6 is the last clean release named in the incident reports, and PyPI quarantined the bad versions 1.82.7 and 1.82.8 after about three hours. Check your installed version with pip show litellm. If you ever ran 1.82.7 or 1.82.8, treat the host as compromised and rotate its credentials.
Which LiteLLM versions were compromised?
Versions 1.82.7 and 1.82.8, published on 24 March 2026. Version 1.82.8 added a litellm_init.pth file that ran at every Python start.
How was LiteLLM compromised?
The attackers stole the PyPI publishing token from LiteLLM's CI pipeline. The pipeline ran the Trivy GitHub Action without a pinned version, and the poisoned action read the token from the runner. The attackers then published to PyPI directly.
Is uninstalling LiteLLM enough after the attack?
No. The malware installs a systemd service at ~/.config/sysmon/sysmon.py and can deploy pods in the Kubernetes kube-system namespace. Remove those, then rotate every credential the host can read.
What did the LiteLLM malware steal?
SSH keys, AWS, GCP and Azure credentials, Kubernetes tokens, Docker credentials, environment files, database credentials, TLS private keys, CI secrets and cryptocurrency wallets. It sent them encrypted to models.litellm.cloud.
Sources
- bleepingcomputer.com/news/security/popular-litellm-pypi-package-compromised-in-teampcp-supply-chain-attack/
- research.jfrog.com/post/litellm-compromised-teampcp/
- snyk.io/blog/poisoned-security-scanner-backdooring-litellm/
- endorlabs.com/learn/teampcp-isnt-done
- microsoft.com/en-us/security/blog/2026/03/24/detecting-investigating-defending-against-trivy-supply-chain-compromise/
More supply chain attacks
- Microsoft durabletask PyPI compromise (TeamPCP) 19 May 2026
- num2words hijack (PyPI phishing campaign / Scavenger malware) 28 Jul 2025
- Ultralytics PyPI compromise (GitHub Actions cache poisoning) 4 Dec 2024
- aiocpa crypto-pay library poisoned release 20 Nov 2024
All 111 attacks in the library · What is a supply chain attack? · How to prevent supply chain attacks
Check the next update before you install it
Vigilance compares the version you trust with the new one. It names the one file that can now do something it could not do before.