On October 21, 2026, a malicious LiteLLM 1.107.0 was published to PyPI and Docker by LiteLLM's own release pipeline. The attacker used three developers' stolen GitHub CLI tokens, which LiteLLM believes were lifted from the logs of an internet-exposed internal LiteLLM deployment. They overrode branch protection, built the release from a lookalike repo (Berri-AI/litellm), approved it, and deleted the run records. The package installed a .pth startup hook that stole cloud, SSH, browser, CI and AI tool credentials plus every provider key in the LiteLLM proxy database, and an hourly remote code loader. It was live for about 1h44m on PyPI and about 2.5h on Docker, with roughly 49,000 downloads. If you installed it: kill the loader, rebuild, and rotate everything that machine could reach.
Introduction
On October 21, 2026, LiteLLM 1.107.0 went out to PyPI and Docker with a credential stealer inside. It was the second time this year that LiteLLM's releases had been compromised.
The first was in March, through a poisoned security scanner. Afterwards, the team did what you're supposed to do: moved releases to a private repo, switched to Trusted Publishing, made Docker tags immutable, and started signing images.
This time, none of those controls failed. The malicious release was built by LiteLLM's real pipeline, published with LiteLLM's real publishing identity, signed, and pushed to the real registries. Every safeguard did exactly what it was configured to do. The attacker just had the credentials of the people the safeguards were built to trust.
Kevin Beaumont's reaction: "LiteLLM got compromised... again."
So how do you poison a release pipeline that was hardened specifically against this?
Turns out, it starts with logs.
Let me walk through each link in this chain.
What Is LiteLLM and Why Attackers Want It
If you haven't used it: LiteLLM is a Python SDK and proxy from BerriAI that puts 100+ LLM providers behind one OpenAI-compatible API. You point your apps at LiteLLM, and LiteLLM holds the keys for OpenAI, Anthropic, Bedrock, Vertex, Azure and the rest.
That makes it one of the most credential-dense pieces of software in a modern stack:
- It runs on developer laptops, in CI jobs, and as a production AI gateway in Kubernetes
- The proxy stores every upstream provider key in its database
- It usually sits next to cloud roles, database URLs and internal service tokens
- It gets about 23 million downloads a week, according to Socket
So a poisoned release lands on the machine that holds the keys for every app behind it.
Layer 1: The Entry Point - An Exposed Internal Gateway
LiteLLM's post-mortem says it found "an unexpected, innocuously named user account" on an internal LiteLLM deployment that was exposed to the public internet.
How the attacker got that account is still unconfirmed. LiteLLM suspects "a recently patched vulnerability," but hasn't said which one.
What the attacker found inside is the important part: the deployment's logs contained GitHub CLI OAuth tokens for three LiteLLM developers.
Why this link broke: An internal tool was reachable from the internet. Internal deployments tend to get weaker auth, slower patching and more verbose logging than production, because "nobody outside can reach it." That assumption stops being true the moment it's exposed.
Layer 2: The Pivot - GitHub Tokens in AI Gateway Logs
Here's where it gets interesting.
Why were GitHub tokens sitting in an LLM gateway's logs at all? LiteLLM's explanation:
"we have observed specific situations in which Claude Code will embed a user's GitHub CLI OAuth token into a response body, and in situations where response bodies are logged, these tokens may appear in LiteLLM logs."
That's LiteLLM's own finding. I couldn't find a public response from Anthropic at the time of writing, so treat the exact mechanism as LiteLLM's account.
But the general problem doesn't depend on the details. An AI gateway sees everything that passes through a model conversation: prompts, tool outputs, file contents, command results. When coding agents work in your terminal, secrets end up in that context all the time. If the gateway logs full request and response bodies, those logs become a store of secrets that nobody protects like one.
GitHub CLI OAuth tokens carry the full permissions of the user. One of the three belonged to a GitHub organization owner. And on October 19, two days before the attack, LiteLLM had temporarily expanded release permissions for two internal engineers to handle daily backports.
Why this link broke: Logging full bodies in an AI gateway is convenient for debugging and terrible for secrets. Combine that with broad, long-lived CLI tokens and you get a log file that can publish a package used by millions.
Layer 3: The Escalation - Turning the Release Pipeline Against Itself
On the morning of October 21, the attacker used the three tokens to walk the release through every gate. All times UTC:
| Time | What happened |
|---|---|
| 08:56 - 10:46 | Ten attacker commits pushed to a lookalike repo, Berri-AI/litellm (note the hyphen) |
| 10:08:29 | GitHub branch protection rejects an unauthorized change to the private release workflow |
| 10:08:34 | Five seconds later, the org owner's token overrides the protection and applies the change |
| 10:46 | The modified workflow starts a staging run, building from Berri-AI/litellm instead of BerriAI/litellm |
| 11:08 | Production pipeline begins |
| 11:11 | A second developer's token satisfies the production approval gate |
| 11:39 - 11:40 | Seven malicious 1.107.0 wheels uploaded to PyPI |
| 11:46 | Infected Docker images published; latest, main-latest and main-stable now point to them |
| 11:53 - 11:54 | A third developer's token deletes the staging and production workflow run records |
Each token had a job: the first changed the pipeline, the second approved the release, the third cleaned up.
The one-line payload injection
The application code was never touched. The attack lived entirely in packaging.
LiteLLM builds its wheels with maturin. The attacker added one line to pyproject.toml:
[tool.maturin]
manifest-path = "litellm-rust/crates/python-bridge/Cargo.toml"
module-name = "litellm.rust_bridge._native"
python-source = "."
+data = "cook"
python-packages = ["litellm_cli"]
That tells maturin to ship whatever is in a cook/ directory as package data, which pip then installs into the root of site-packages. The cook/ directory held the payload. It wasn't in the published source tarball, and the official v1.107.0 git tag doesn't contain the change either. If you audited the tag, you saw clean code.
The "Verified" badge and the provenance nobody read
Two more details matter here:
- The attacker's commits in the lookalike repo were authored as
Berri-AI <[email protected]>, and nine of the ten showed GitHub's "Verified" badge. That badge means GitHub signed the commit for whichever account made it. It says nothing about whether that account is who you think it is. - The Docker images carried valid build provenance. Socket noticed that the provenance listed the source owner as
Berri-AI, one hyphen away from the realBerriAI. Thev1.106.2provenance shows the real owner. The signature was valid, but the source repo in it was wrong.
Why this link broke: Every control in the pipeline trusted a credential as a stand-in for a person. Branch protection, approval gates and audit logs are all two-person rules on paper. With three stolen tokens, one attacker was all three people.
Layer 4: The Payload - What the LiteLLM 1.107.0 Malware Does
Each malicious wheel installed three extra files into site-packages:
| File | Role |
|---|---|
cook.pth | Startup hook: makes Python import cook on every interpreter start |
cook.py | Credential stealer that calls itself privcollect |
sitecustomize.py | Detached loader daemon that checks for remote code every hour |
How the cook.pth startup hook works
Python's site module processes .pth files in site-packages at startup, and any line beginning with import gets executed. So cook.pth runs the stealer every time Python starts in that environment - your app, a test run, pip itself, a one-off script. You never had to import litellm.
sitecustomize.py is another module Python imports automatically at startup. Wiz said using both .pth and sitecustomize.py together "appears to be the first documented case in the wild."
What the stealer collected
The stealer ran 16 collection modules in a background thread. Per the analysis in GitHub issue #47826 and StepSecurity's write-up:
| Category | Targets |
|---|---|
| Cloud | AWS, Azure, GCP and Kubernetes credentials; AWS IMDSv2 and ECS task role credentials (validated with sts:GetCallerIdentity); GCP and Azure metadata tokens |
| Developer | SSH keys, GPG keys, .git-credentials, GitHub CLI, .npmrc, .pypirc, Maven, Gradle, Cargo, Composer, Docker configs, .env files, *.pem / *.key / *.pfx |
| CI / infra | Kubernetes service account tokens, /run/secrets, GitLab Runner, Jenkins, Vault, Terraform, Packer |
| Browsers | Chromium saved passwords (decrypted), cookies and web data; Firefox logins |
| AI tools | Configs and tokens for 20+ AI coding tools, including Claude, Codex, Gemini, Cursor, Windsurf, Copilot and Hugging Face tokens |
| Processes | Environment variables of every readable process on Linux |
| LiteLLM proxy | If DATABASE_URL is set, it dumps the proxy's credentials and model tables - every upstream provider key |
| History | Shell, database and REPL histories, network info |
The data was encrypted (AES-256-CBC, key wrapped with RSA-4096) and sent over plain HTTP to www.litellm.dev/healthcheck - a domain registered on October 13 to look like LiteLLM infrastructure. The real project domain is litellm.ai. Because of the encryption, you can't tell from a packet capture what was taken.
The dormant second stage
The sitecustomize.py loader forked a detached daemon, took a lock file so only one copy ran, and every hour read a domain name from a file in the attacker's GitHub repo. If a domain was there, it would download Python code from it and execute it.
At release time that file was empty, so the second stage never fired, and GitHub took the repo down that afternoon. But the daemon keeps running on any infected host until you kill it. StepSecurity's warning is worth repeating: "killing the daemon is part of recovery, not just removing the package."
On Windows, the loader can't fork and fails silently, but the stealer still runs.
Layer 5: The Fallout
Exposure window
| Artifact | Window (UTC, Oct 21) |
|---|---|
PyPI litellm==1.107.0 (all 7 wheels: macOS, Linux glibc and musl, Windows) | 11:39 - 13:23 |
GHCR v1.107.0, latest, main-latest, main-stable (litellm, litellm-database, litellm-non_root) | 11:46 - 13:51 |
Docker Hub litellm/litellm same tags | 11:46 - 14:20 |
Wiz counted about 49,000 downloads of the malicious version, citing ClickPy. That number includes mirrors and CI caches, so it isn't a count of victims, but it's still a large number. Anything with an open-ended constraint like litellm>=1.100 or a floating latest image tag picked it up automatically.
Detection was fast. Socket's scanner flagged the wheels about seven minutes after they hit PyPI, and the compromise was reported publicly in GitHub issue #47826 at 12:06 UTC. LiteLLM had the package off PyPI within about 1h44m.
The stolen keys got used
The stolen credentials were put to use quickly. Wiz observed the attacker validating stolen credentials about four and a half hours after exfiltration, between 16:20 and 17:01 UTC, from two IPs:
- Each harvested AWS role credential (from CI runners and Kubernetes nodes) was checked with
sts:GetCallerIdentity - Then came Bedrock and model-listing calls, which Wiz called "consistent with LLMjacking" - using stolen cloud access to run expensive AI models on the victim's bill
- In a small number of environments, the attacker enumerated IAM roles, users and access keys, and checked CloudTrail configuration
Response
LiteLLM's post said the compromise was "Contained," with the official v1.107.0 tag clean and "All previous versions are safe." Enterprise customers using LiteLLM's private registry were not affected. CEO Krrish Dholakia said: "Our immediate priority is ensuring customers are protected and preventing this from happening again."
The safe version to pin is 1.106.2.
Why LiteLLM's March Hardening Didn't Stop It
After March, LiteLLM's pipeline had most of what supply chain guidance recommends. Here's how each control held up:
| Control added after March | What the attacker did |
|---|---|
| Releases from a private repo | Used developer tokens that already had access |
| Branch protection on the release workflow | Org owner's token overrode it in five seconds |
| Approval gate for production | A second stolen token approved it |
| Trusted Publishing to PyPI | Ran the real pipeline, so PyPI accepted the real identity |
| Immutable Docker tags | Published a brand-new version instead of retagging an old one |
| Signed images | The legitimate pipeline signed them |
| Audit trail of workflow runs | A third stolen token deleted the run records |
LiteLLM put it this way: the attacker "had to compromise multiple independent security controls to be successful." That's true, but the controls weren't independent. They all bottomed out in the same thing - a GitHub token - and the attacker had three.
Trusted Publishing and signing answer the question "did this come from our pipeline?" They don't answer "should our pipeline have built this?" When the pipeline itself is hijacked, the signature is real.
March vs October
| March 2026 | October 2026 | |
|---|---|---|
| Versions | 1.82.7, 1.82.8 | 1.107.0 (PyPI + Docker) |
| Entry | Poisoned Trivy security scanner in CI (TeamPCP) | Exposed internal LiteLLM deployment |
| What was stolen to publish | PyPI publishing token | Three developers' GitHub CLI tokens |
| Startup hook | litellm_init.pth | cook.pth + sitecustomize.py |
| Exfil domain | models.litellm.cloud | www.litellm.dev |
Socket said it found no evidence linking the two, noting different encryption keys, exfiltration and backdoor behavior - while adding, "That doesn't rule out the same operator using different tooling." Wiz also said the October malware showed strong signs of AI-assisted writing.
LiteLLM 1.107.0 Attack Timeline
| Date (UTC) | Event |
|---|---|
| Mar 24, 2026 | First compromise: LiteLLM 1.82.7 and 1.82.8 published with stolen PyPI token via the Trivy compromise |
| Oct 13 | litellm.dev registered; attacker GitHub account letters9813 created |
| Oct 18 | Dead-drop repo for the remote loader created |
| Oct 19 | LiteLLM temporarily expands release permissions for two engineers |
| Oct 21, 08:56 | Attacker starts pushing commits to lookalike Berri-AI/litellm |
| Oct 21, 10:08 | Branch protection rejects the workflow change, then gets overridden |
| Oct 21, 11:39 | Malicious wheels on PyPI |
| Oct 21, 11:46 | Malicious Docker images live; Socket flags the wheels |
| Oct 21, 11:53 | Workflow run records deleted |
| Oct 21, 12:06 | Public report in GitHub issue #47826 |
| Oct 21, 13:23 | PyPI removes 1.107.0 |
| Oct 21, 14:20 | Docker Hub tags removed or repointed to clean images |
| Oct 21, 16:20 - 17:01 | Wiz observes stolen AWS credentials being validated and Bedrock probed |
Am I Affected? How to Check, Clean Up and Recover
Step 0: Check if you installed LiteLLM 1.107.0
Check from the shell, not from Python. Every Python start in an infected environment re-runs the payload, so don't use python, pip or uv to investigate an environment you suspect.
# Payload files anywhere on the box
find / -path '*site-packages*' \( -name 'cook.pth' -o -name 'cook.py' \) 2>/dev/null
find / -path '*site-packages*' -name 'litellm-1.107.0.dist-info' 2>/dev/null
# Host markers
ls -la /tmp/.pc_once_72129118c59f5636c0bb /tmp/remote_code_loader.lock 2>/dev/null
# Lockfiles and requirements in your repos
grep -rnE 'litellm[^0-9]*1\.107\.0' --include='*.txt' --include='*.lock' --include='*.toml' .
# Docker images you pulled
docker images --digests | grep -i litellm
Also check for any sitecustomize.py in site-packages you didn't put there. For containers, check which image digest your deployments pulled on October 21 - a floating latest tag tells you nothing about what was running at the time.
Finding the files confirms exposure. Not finding the marker file doesn't clear you: the marker is only written after a successful upload, and you may have already rebuilt the environment.
Step 1: Kill the loader first
Before you clean anything, stop the daemon:
# Find and kill whatever holds the loader's lock
lsof /tmp/remote_code_loader.lock
kill -9 <pid>
Then remove cook.pth, cook.py, sitecustomize.py and their __pycache__ entries from every affected site-packages. Better yet, don't repair - rebuild the virtualenv or image from scratch.
Step 2: Pin a clean version
# In a fresh virtualenv, not the infected one
pip install 'litellm==1.106.2'
For Docker, pin v1.106.2 by digest, not by tag, and purge cached v1.107.0 layers from your registries, pull-through caches and PyPI mirrors (some mirrors kept serving it after PyPI removed it).
Step 3: Rotate, in the right order
If 1.107.0 ran on a host with outbound internet access, assume exfiltration succeeded. Rotate everything that host could reach, roughly in order of blast radius:
| Priority | What to rotate |
|---|---|
| 1 | Cloud credentials: IAM role sessions, access keys, service accounts, Kubernetes tokens |
| 2 | Source and package registry tokens: GitHub, PyPI, npm, Docker registries |
| 3 | LiteLLM proxy: every provider API key in the database, the master key, salt key, virtual keys, and the DATABASE_URL password |
| 4 | CI secrets, Vault tokens, Terraform credentials |
| 5 | SSH and GPG keys, TLS private keys |
| 6 | AI tool tokens (Claude, Codex, Cursor, Gemini, Copilot, Hugging Face) |
| 7 | Browser-saved passwords and sessions on developer machines |
Rotate from a clean machine. Rotating from an infected one just hands the new secrets over.
Step 4: Hunt for credential abuse
# Who called GetCallerIdentity around the exposure window?
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=GetCallerIdentity \
--start-time 2026-10-21T11:00:00Z --end-time 2026-10-22T00:00:00Z
Look for your instance or task role credentials being used from IPs outside your infrastructure, Bedrock ListFoundationModels or invocation calls you don't recognize, and IAM enumeration (ListRoles, ListUsers, ListAccessKeys). Check your provider dashboards (OpenAI, Anthropic, etc.) for usage spikes on keys that lived in the LiteLLM database.
Step 5: Block and alert
- Block
litellm.devandwww.litellm.devat DNS and egress - Alert on any request to a
/codepypath - that means second-stage code ran and your scope is much bigger - Alert on new
.pthorsitecustomize.pyfiles appearing in site-packages
Indicators of compromise
| Type | Value |
|---|---|
| Exfil domain | litellm[.]dev, www.litellm[.]dev/healthcheck (plain HTTP POST) |
| Exfil header | X-Token: XWiA8gZNa7NcX2XRoAEb |
| Second stage | http://<domain>/codepy |
| Dead drop | raw.githubusercontent.com/letters9813/pythonclient-test/main/domain.txt (deleted) |
| Lookalike repo | github.com/Berri-AI/litellm, commit 20535d8fa11f786a6c24df7488a0e449ed5f09ad |
| Attacker identity | Berri-AI <[email protected]> |
| Files | cook.pth, cook.py, sitecustomize.py in site-packages |
| Markers | /tmp/.pc_once_72129118c59f5636c0bb, /tmp/remote_code_loader.lock, env PRIVCOLLECT_ACTIVE=1 |
| Credential validation IPs (Wiz) | 168.100.8[.]57, 165.227.201[.]8 |
| Docker Hub image index | sha256:1bbcb1443bc962e45f5aad53fe3d2c30600e0379715fb6c664cdd3ac126c339e |
Per-wheel SHA-256 hashes and every image digest are in GitHub issue #47826 and LiteLLM's incident post.
Long-term hardening
If you consume packages:
| Area | Action | Why |
|---|---|---|
| Pin exactly | Lock exact versions with hashes (uv lock, pip install --require-hashes) | litellm>= pulled 1.107.0 automatically |
| Release cooldown | Don't install versions younger than a few days (uv exclude-newer, Renovate minimumReleaseAge, Dependabot cooldown) | This one was live for under two hours |
| Pin images by digest | Never deploy latest or main-stable | Floating tags pointed at the malware for hours |
| Egress control | Allowlist outbound traffic from CI runners and gateways | No egress, no exfiltration |
| Short-lived cloud creds | IMDSv2, scoped roles, short sessions | Limits what a stolen session can do |
| Watch startup hooks | Alert on new .pth / sitecustomize.py files | The whole attack lived there |
If you run an AI gateway:
| Area | Action | Why |
|---|---|---|
| Don't log full bodies | Turn off or redact request/response body logging in production | Gateway logs held the tokens that started this |
| Never expose internal gateways | Put them behind SSO or a private network | The entry point was an internet-facing internal deployment |
| Lock down the key database | Restrict who and what can reach DATABASE_URL; consider a secrets manager for provider keys | The stealer went straight for it |
| Per-team virtual keys | Issue scoped, revocable keys instead of sharing provider keys | Makes rotation and blast radius manageable |
If you publish packages:
| Area | Action | Why |
|---|---|---|
| Scoped, short-lived tokens | Prefer fine-grained, expiring tokens over broad CLI OAuth tokens for org admins | One owner token beat branch protection |
| Alert on overrides and deletions | Watch GitHub audit log events like protected_branch.policy_override and workflows.delete_workflow_run | Both happened here, minutes apart |
| Check provenance content | Verify the source repo in your build provenance, not just that a signature exists | The provenance said Berri-AI the whole time |
| Diff artifacts against the tag | Rebuild from the tag and compare before or right after publishing | The tag was clean; the wheels weren't |
| Strong approvers | Require approvals from hardware-key-backed sessions, not tokens | A stolen token approved production |
The Bigger Picture
Let's zoom out.
1. AI gateways are high-value targets now. A LiteLLM proxy holds every model key a company has, sits next to cloud credentials, and logs everything developers and agents send to models. This payload went straight for the proxy database and for AI coding tool configs.
2. Logs are a secret store whether you meant them to be or not. Agents read files, run commands and pass results through model conversations. Anything that enters that context can end up in a gateway log. If you log bodies, you're storing secrets.
3. Signatures prove origin, not intent. Trusted Publishing, signed images and provenance are all valuable, and they did their job here. They proved the artifacts came from LiteLLM's pipeline. They can't prove the pipeline wasn't hijacked. You have to read what the provenance says, not just check that it exists. Same lesson as the eMudhra CA key compromise a few days earlier: a valid signature only tells you which key signed something.
4. Two-person rules need two people. Branch protection plus approvals plus audit logs looks like defense in depth. When every one of them is satisfied by a token, three stolen tokens make one attacker into a whole team.
5. AI tooling keeps getting hit in 2026. LiteLLM in March, the Vercel breach through an AI tool's OAuth access in April, and LiteLLM again in October. Attackers go where the credentials are, and AI tooling now holds a lot of them.
FAQ
Which LiteLLM versions are affected?
Only litellm==1.107.0 on PyPI (all seven wheels) and the v1.107.0 Docker images on GHCR and Docker Hub, plus the latest, main-latest and main-stable tags while they pointed at it on October 21. LiteLLM says all previous versions are safe. Pin 1.106.2.
Is LiteLLM safe to use now?
The malicious version was removed from PyPI and Docker on October 21, and LiteLLM revoked the compromised credentials. Pin an exact earlier version such as 1.106.2, pin Docker images by digest, and wait for LiteLLM's full root cause report before moving to new releases.
How do I know if I installed LiteLLM 1.107.0?
Look for cook.pth, cook.py or a litellm-1.107.0.dist-info folder in any site-packages directory, the lock file /tmp/remote_code_loader.lock, and 1.107.0 in your lockfiles. Check from the shell, not from Python, because starting Python in an infected environment re-runs the payload.
What did the LiteLLM malware steal?
Cloud credentials (AWS, Azure, GCP, Kubernetes), SSH and GPG keys, GitHub and package registry tokens, browser passwords and cookies, CI secrets, AI coding tool tokens, environment variables of running processes, and every provider API key stored in the LiteLLM proxy database.
Did Claude Code cause the LiteLLM hack?
Not directly. LiteLLM says it has seen Claude Code put a user's GitHub CLI token into a response body, which its gateway then logged. The attacker read those logs on an internal deployment that was exposed to the internet. The underlying problems were the exposed deployment and logging full request and response bodies. I couldn't find a public response from Anthropic at the time of writing.
Is this the same attack as the March 2026 LiteLLM compromise?
There's no evidence linking them. March came through the poisoned Trivy scanner and a stolen PyPI token; October came through stolen GitHub tokens. Socket found different encryption keys, exfiltration and backdoor behavior, but said that doesn't rule out the same operator.
Conclusion
An internal LiteLLM deployment was exposed to the internet. Its logs held three developers' GitHub tokens. One token overrode branch protection, one approved the release, one deleted the evidence. The real pipeline built a poisoned package from a lookalike repo, signed it, and published it to PyPI and Docker. For under two hours, every unpinned install got a credential stealer - and within five hours, the stolen keys were being tested against Bedrock.
All of this got past controls that LiteLLM added specifically because of the attack in March.
If you installed 1.107.0, don't just upgrade. Kill the loader, rebuild, and rotate everything that machine could reach. If you didn't, use this as the push to pin exact versions, pin images by digest, and stop logging full bodies in your AI gateway.
Signed doesn't mean safe: LiteLLM 1.107.0 was built, signed and published by the real pipeline using stolen developer tokens that leaked through AI gateway logs. If you installed it, kill the loader before touching Python, rebuild from scratch, and rotate every credential the host could reach. Everyone else: pin exact versions with hashes, pin images by digest, add a release cooldown, and lock down your AI gateway's logs and key database.
References
- Contained: Oct 21, 2026 LiteLLM release v1.107.0 Compromised - LiteLLM
- litellm 1.107.0 compromised - GitHub issue #47826
- litellm 1.107.0 Compromised on PyPI - StepSecurity
- LiteLLM PyPI Package and Docker Images Compromised - Socket
- LiteLLM Compromised, Steals Credentials - Wiz
- LiteLLM Suspects GitHub Token Leak in AI Gateway Logs - The Hacker News
- LiteLLM hit by second supply chain attack this year - Help Net Security
- LiteLLM says hackers poisoned it with GitHub tokens leaked via Claude Code - The Next Web
- Trivy compromise hits LiteLLM - The Register (March 2026)
- Poisoned security scanner backdooring LiteLLM - Snyk (March 2026)