LiteLLM 1.107.0 Steals the Keys It Was Guarding
LiteLLM 1.107.0 on PyPI shipped a credential stealer. If your proxy ran it, every provider key is burned. Here's the playbook.
Yesterday's routine dependency bump was the breach. LiteLLM 1.107.0, published to PyPI, was trojanized — install it and you get a credential stealer plus a backdoor, researchers confirmed today.
Here's the bitter part: LiteLLM is the open-source proxy teams run in front of OpenAI, Anthropic, Azure, and Bedrock. Its entire job is holding every provider key you own. The guard got caught picking the locks.
Why this matters
Most supply-chain hits expose whatever one app happens to touch. This one is worse. A LiteLLM deployment typically holds long-lived, high-limit keys for every AI vendor you use — and often an AWS task role or GCP service account for Bedrock and Vertex on top. That's provider spend, your cloud account, and sometimes org-wide Azure credentials in a single process.
Attackers go after the AI stack because it's new, assembled fast, and full of keys nobody rotates. Your LLM gateway is now the most valuable process in your cluster. Treat it like a database full of plaintext passwords, because functionally it is.
How it works
PyPI compromises follow a script: someone gets publish access — a leaked maintainer token, a hijacked account — and pushes one malicious version. Auto-upgraders and fresh CI runs pull it within hours.
When PyPI yanks the file, everyone relaxes. Except yanking doesn't reach your infrastructure. pip and uv cache wheels locally, Docker bakes them into layers, some teams vendor wheels into the repo. Days after the takedown, a cache hit or an old image still installs the poisoned artifact. The registry recovered. Your build cache didn't.
Unhashed lockfiles don't save you either. They pin names and versions, and the attacker shipped a brand-new version precisely to slip past those pins.
Where this helps
- Audit every place
litellmruns: the prod proxy, but also eval harnesses, agent sandboxes, notebooks. Ad-hoc environments are where upgrades happen unsupervised. - If 1.107.0 ran anywhere, rotate everything it could reach — provider API keys, plus the cloud role if it talked to Bedrock or Vertex. Then scan CloudTrail or GCP audit logs for token calls you don't recognize.
- Generate hashed locks so a swapped file fails the install:
pip-compile --generate-hashesoruv lock. Hashes pin the artifact, not just the version string. - Rebuild proxy images with
docker build --no-cacheonce, so no poisoned layer survives.
Watch out
- Don't "fix" this by jumping to the newest release unread. Pin to the last version you actually audited and read the diff.
- Hash pinning only works if the entire tree is hashed. One unhashed dependency reintroduces the hole.
- Rotating provider keys isn't enough if the backdoor ran with an IAM role — those need revocation and log review too.
Try it yourself
# 1. Find every environment running the proxy
pip list --format=freeze | grep -i litellm
docker exec my-litellm pip list --format=freeze | grep -i litellm
# 2. See 1.107.0? Treat every key in that env as public.
# Rotate provider keys and cloud creds before touching anything else.
# 3. Reinstall clean — and skip any poisoned wheel in local caches
pip install --no-cache-dir --force-reinstall 'litellm!=1.107.0'
uv cache clean litellmTL;DR
- What happened: LiteLLM 1.107.0 on PyPI shipped a credential stealer and a backdoor — and cached copies outlive any takedown.
- Why it matters: your LLM proxy holds every provider key, often plus cloud credentials. It's the perfect heist target.
- Try today: grep your environments for litellm, purge your package caches, and move your lockfile to hash-pinned.