The LiteLLM supply-chain attack: what happened and how to protect your Python and Docker projects
A malicious LiteLLM 1.107.0 was published to PyPI and Docker on October 21, 2026 and stole credentials from every machine that installed it. How the attack worked, how to check if you're affected, what to rotate, and the habits that stop the next one.
Quick answer: On October 21, 2026, attackers published a malicious LiteLLM 1.107.0 to PyPI and Docker. It installed a credential stealer that ran every time Python started. If you installed 1.107.0, treat every secret that machine or container could read as stolen: remove the version, pin 1.106.2 (or a later clean release), rebuild, and rotate your keys.
LiteLLM is a popular open-source library and proxy that lets apps call many AI model providers through one API. That popularity is exactly why attackers target it: one poisoned release reaches thousands of developer machines, servers and CI pipelines that hold valuable API keys and cloud credentials.
What is a supply-chain attack?
Most attacks target your code. A supply-chain attack targets something your code depends on: a package, a build tool or a container image. You install the update you trust, and the attacker's code comes with it.
Modern projects pull in hundreds of dependencies, and many update automatically. That makes package registries such as PyPI (Python), npm (JavaScript) and Docker Hub high-value targets.
What happened, step by step
- Attackers got developer access. They used GitHub CLI OAuth tokens belonging to three LiteLLM engineers.
- They pushed a release through the normal pipeline. One account changed the release pipeline and triggered a release, a second approved it, and a third deleted workflow records, which made the investigation harder.
- Malicious builds went live on PyPI and Docker. Reports say they were available for about three hours and were downloaded tens of thousands of times before removal.
- The payload stole credentials. It looked for cloud credentials (AWS, Google Cloud, Azure, including instance metadata), developer keys and AI tool sessions, and a second stage could fetch more code from a remote server.
How did the attackers get the tokens in the first place? LiteLLM's working theory is that they were harvested from logs on an internet-exposed internal deployment. At the time of writing, the company says it hasn't confirmed the initial access path, so treat that detail as provisional.
This was reported as the second LiteLLM compromise of 2026, after a separate incident in March that affected versions 1.82.7 and 1.82.8.
The clever (and scary) part: a .pth file
Reports say the malicious package dropped a .pth file into Python's site-packages folder. Python automatically processes .pth files at startup, and they can execute code.
That means the stealer ran every time Python started on that machine, even in projects that never imported LiteLLM. Uninstalling the package is therefore not enough on its own; you need to make sure that file is gone, or better, rebuild the environment.
Am I affected? How to check
Python environments
pip show litellm | grep -i versionCheck every virtual environment, Conda environment and server, not just your laptop. Then look for unexpected .pth files:
python -c "import site; print(site.getsitepackages())"
# then list .pth files in those folders and inspect any you don't recognise
ls -la /path/to/site-packages/*.pthMost .pth files are harmless (for example from editable installs). Look for ones you can't explain, especially recently modified ones.
Docker
docker images | grep -i litellm
docker run --rm <your-image> pip show litellmIf any image contains 1.107.0, or was built from one, consider it compromised.
CI pipelines and lockfiles
Search your lockfiles (requirements.txt, poetry.lock, uv.lock, Pipfile.lock) and recent CI logs for litellm==1.107.0 or an unpinned litellm that may have resolved to it on October 21.
If you installed 1.107.0: clean-up steps
-
Isolate affected machines and containers.
-
Rebuild environments from scratch instead of just uninstalling. Pin a known-good version:
requirements.txt litellm==1.106.2 -
Rotate every secret the environment could read: cloud keys (AWS, GCP, Azure), AI provider API keys (OpenAI, Anthropic and others), GitHub tokens, database passwords, SSH keys and anything in
.envfiles. -
Review cloud audit logs (for example AWS CloudTrail) for activity from those credentials since October 21.
-
Revoke and reissue CI/CD tokens used by affected pipelines.
Rotation is the step people skip, and it's the one that matters most. A stolen key keeps working until you revoke it.
How to protect your projects from the next one
| Habit | Why it helps |
|---|---|
| Pin exact versions and commit lockfiles | A new malicious release isn't installed automatically |
Use hash checking (pip install --require-hashes, uv lockfiles) |
Even a re-uploaded file with the same version fails to install |
| Delay new versions (a few days' cooldown in Dependabot/Renovate) | Most malicious releases are caught and pulled within hours |
| Least-privilege secrets | A stolen key from a dev laptop shouldn't unlock production |
| Short-lived credentials (OIDC in CI, SSO for cloud) | Stolen tokens expire quickly |
| Separate build and runtime secrets | Build tools never see production keys |
| Don't log tokens | Logs are a common, overlooked leak, including AI gateway and tool logs |
| Scan dependencies (pip-audit, OSV, your registry's security alerts) | You hear about known-bad versions fast |
Example: install with hashes
pip-compile --generate-hashes requirements.in
pip install --require-hashes -r requirements.txtExample: a cooldown for dependency updates
Configure Dependabot or Renovate to wait a few days before proposing new versions (Renovate calls this minimumReleaseAge). Most poisoned releases are detected within that window.
Lessons for AI teams
AI tooling sits in a dangerous spot: it's new, it updates constantly, and it's surrounded by high-value API keys. A few principles from this incident:
- Treat AI gateways and proxies as production infrastructure: patch them, restrict network access, and never expose internal deployments to the internet.
- Keep secrets out of prompts, responses and logs. Agents and coding assistants can echo tokens into output that ends up in logs.
- Protect maintainer accounts: hardware security keys, short token lifetimes and release approvals that can't all be satisfied by a single compromised machine.
For a deeper look at how attackers abuse AI systems, see prompt injection explained and AI coding agents: a workflow that ships reliable code.
Frequently asked questions
What happened in the LiteLLM supply-chain attack?
On October 21, 2026, attackers used stolen GitHub CLI tokens from three LiteLLM engineers to publish a malicious LiteLLM 1.107.0 to PyPI and Docker. It contained a credential stealer that targeted cloud keys, developer tokens and AI tool sessions.
Which LiteLLM version is safe?
Version 1.107.0 was malicious. Pin litellm==1.106.2 or another release published before October 21, 2026, or a later release the LiteLLM team confirms as clean, and rebuild affected environments.
Is uninstalling LiteLLM 1.107.0 enough?
No. The malware reportedly installed a .pth file that ran on every Python start, and it may already have stolen credentials. Rebuild environments from scratch and rotate every secret the machine could access.
How do I check if I installed the malicious LiteLLM?
Run pip show litellm in every environment, check Docker images with docker run --rm IMAGE pip show litellm, and search lockfiles and CI logs for litellm==1.107.0 or unpinned installs around October 21, 2026.
What should I rotate after a supply-chain compromise?
Rotate everything the environment could read: cloud provider keys, AI provider API keys, GitHub and CI tokens, database passwords, SSH keys and values in .env files. Then review cloud audit logs for activity using the old credentials.
How can I prevent supply-chain attacks in Python?
Pin exact versions with lockfiles, install with hash checking, add a cooldown before adopting new releases, scan dependencies with tools like pip-audit, use short-lived credentials and keep production secrets away from developer machines and build steps.
What is a .pth file in Python?
A .pth file in site-packages is processed when Python starts. It normally adds paths, but lines starting with import can run code, which is why malware can use it to execute on every Python start.
Comments