CVE
Not assigned
CWE
CWE-200, CWE-494, CWE-506, CWE-522
Affected Surface
- PyPI package `litellm` versions `1.82.7` and `1.82.8`
- Python developer workstations, CI runners, AI gateway build jobs, and container builds that installed those versions on or after 2026-03-24
- Transitive consumers that resolved unpinned `litellm` during the exposure window, including AI agent frameworks, MCP tooling, and LLM orchestration stacks
- Secrets reachable from those hosts, including cloud credentials, GitHub or GitLab tokens, package-publishing credentials, Kubernetes tokens, SSH keys, and AI-provider API keys
The most important application-security update from the last three days is not a brand-new PyPI upload. It is the August 11-14 disclosure wave that finally put blast-radius numbers behind the March litellm compromise. Public follow-on reporting now ties the two malicious PyPI versions, 1.82.7 and 1.82.8, to a reconstructed exposure set of roughly 434,000 CI/CD pipelines and 2,500+ organizations, with StepSecurity’s analysis of the same disclosure counting 78,330 secrets across 2,186 organizations over the March 19-24 TeamPCP window.
That does not mean LiteLLM alone was proven to compromise every named organization. CloudSEK and SecurityWeek are careful about the wording: the large counts describe reconstructed exposure, not confirmed attacker use of every credential and not a clean LiteLLM-only install census. SecurityWeek’s update also notes SOCRadar’s view that many of the named organizations were likely exposed earlier through the upstream Trivy stage. That nuance is exactly why this story matters. The technical lesson is not “a popular AI package got popped.” It is that one bad release path inside an AI-adjacent package ecosystem can turn a short registry window into a long-lived credential incident across pipelines, caches, and downstream publishers.
What was actually compromised
The directly confirmed malicious package artifacts remain narrow:
| Package | Versions | Execution edge | What changed |
|---|---|---|---|
litellm | 1.82.7 | import-time execution | malicious payload embedded in litellm/proxy/proxy_server.py |
litellm | 1.82.8 | Python startup | same payload plus litellm_init.pth, which executes on interpreter startup |
LiteLLM’s March advisory and the later GitHub issue both line up on those version boundaries. The official Docker image path was not affected because it pinned dependencies rather than resolving the hostile PyPI releases during the exposure window.
That narrow artifact list is important because the August numbers are easy to over-read. The broad organization and pipeline counts come from the later exposure dataset, not from a public package list containing hundreds of separately trojanized LiteLLM versions. Defenders should therefore keep two ideas separate:
direct LiteLLM artifact exposure:
litellm==1.82.7
litellm==1.82.8
broader TeamPCP credential-exposure dataset:
Trivy
LiteLLM
other adjacent March pivots
downstream secrets and CI traces
Why 1.82.8 was worse than 1.82.7
The most useful technical distinction in the public evidence is the trigger boundary.
According to LiteLLM’s incident issue, the March 24 packages differed like this:
1.82.7 -> payload in proxy_server.py -> triggers when the affected path is imported
1.82.8 -> payload in proxy_server.py + litellm_init.pth -> triggers on any Python startup
That .pth detail changes incident scoping materially. A malicious postinstall hook is dangerous, but it is at least tied to the installation moment. A .pth file is worse for Python-heavy environments because it shifts execution to the interpreter itself. In practical terms:
python starts
-> site-packages processes .pth files
-> litellm_init.pth launches the attacker path
-> exfiltration runs even if your code never imports LiteLLM
That is why March responders kept stressing find ... -name "litellm_init.pth" rather than only auditing lockfiles. By August, the follow-on reporting makes the operational consequence clearer: pipelines and workstations may have kept leaking secrets after the original package removal window because the real boundary was no longer “who ran pip today?” but “which hosts executed Python after the hostile file landed?”
The data theft path was a host-compromise path, not a package-integrity footnote
The official LiteLLM advisory, the March incident issue, the oss-security posting, and later coverage all agree on the rough payload behavior:
- collect secrets from environment variables and disk
- reach for cloud and cluster credentials already present on the host
- encrypt the bundle
- exfiltrate it to
models.litellm.cloud - establish persistence or a follow-on execution path
The named secret targets are the reason the August blast-radius story matters to AppSec teams. Public reporting consistently places these classes in scope:
- SSH keys
- GitHub and GitLab tokens
- Docker and package-publishing credentials
- AWS, GCP, and Azure credentials
- Kubernetes service-account tokens
- database and LDAP configuration
.envfiles and CI/CD secrets- AI-provider API keys
- shell histories and developer-host leftovers that reveal additional trust paths
LiteLLM’s March issue also attributes the exfiltration path to AES-256-CBC plus an embedded RSA-4096 public key before the upload to https://models.litellm.cloud/. That design choice matters because it shows the operator expected defenders to recover artifacts and network traces. The encryption was there to keep the stolen content useful to the attacker even if the transfer itself was later captured.
The August reporting changes the scale, not the root cause
The direct compromise chain still starts upstream. LiteLLM’s own advisory says the PyPI publish path was likely reached through the earlier Trivy compromise. SecurityWeek describes the same sequence more plainly:
compromised Trivy dependency
-> LiteLLM CI pipeline consumes it
-> publish credentials exposed
-> malicious LiteLLM releases land on PyPI
-> pipelines and developer hosts install them
-> secrets leave the environment
That chain is worth spelling out because it shows why AI infrastructure packages are such attractive relay points. LiteLLM sits close to:
- model-provider API keys
- cloud credentials used to deploy or scale the gateway
- CI secrets used to publish downstream software
- source-control tokens used by automation around model routing, evaluation, and agents
So even though the bad versions were only live for roughly forty minutes, the package sat at a high-value intersection of identity, build automation, and AI control-plane access.
What the new exposure numbers do and do not prove
CloudSEK’s August report gives defenders a reason to revisit March assumptions, but it also needs careful reading.
What it does prove
- the March TeamPCP campaign left a much larger secret dataset than many teams assumed
- the affected environment set spanned multiple CI platforms, not just one vendor
- a short-lived package compromise can become a months-later credential problem
- AI-adjacent dependency paths are now a credible route into cloud, source control, and package publication
What it does not prove
- that every named organization directly installed LiteLLM
- that every credential in the reconstructed dataset was successfully abused
- that package removal alone ended the incident
The cleanest way to interpret the reporting is:
March LiteLLM artifact compromise = proven
August dataset scale-up = strong reason to re-scope the incident
organization-level compromise = must be validated per environment
That distinction keeps the article accurate while still preserving the operational urgency. If your environment touched the bad LiteLLM versions, the broad dataset should lower your threshold for rotating secrets, not raise your threshold because attribution feels messy.
Why this matters beyond LiteLLM
The August disclosure is really a study in how package compromise behaves in modern delivery systems.
The vulnerable trust path was not just:
pip install litellm
It was:
untrusted upstream credential event
-> trusted package publish
-> cached resolver or scheduled build
-> Python startup hook or import path
-> runner or workstation secrets
-> downstream registry or repo compromise
That is why the story belongs beside earlier TeamPCP coverage, Trivy, KICS, Telnyx, TanStack, and the later keyv / cacheable ChainDrop wave. The common boundary is not the language ecosystem. It is the host that already holds enough identity to become the next publisher.
Detection and scoping
Start with explicit version and artifact checks:
rg -n "litellm(==|===)?1\\.82\\.(7|8)" \
requirements*.txt poetry.lock uv.lock Pipfile.lock
pip show litellm
find /usr/lib/python3*/site-packages/ -name "litellm_init.pth"
find "$HOME/.local/lib" -name "litellm_init.pth"
Then hunt for public IOCs and persistence markers named in the advisories and follow-on reporting:
rg -n \
"models\\.litellm\\.cloud|checkmarx\\.zone|sysmon\\.service|System Telemetry Service|tpcp\\.tar\\.gz" \
/etc/systemd "$HOME/.config" .
And do not scope only by files. Query runner and workstation telemetry for:
- outbound traffic to
models.litellm.cloud - outbound traffic to
checkmarx.zone - Python processes spawning unexpected child commands
- pipeline runs from March 24, 2026 that resolved
litellm==1.82.7or1.82.8 - package-publishing or source-control activity that began after those runs
If you are a Python-heavy organization, add one more assumption to your hunt plan: 1.82.8 may have executed on systems that never used LiteLLM at runtime, because Python startup itself was the trigger.
Response guidance
If an affected environment installed or ran either malicious version:
- treat the host as a credential-exposure event, not just a dependency-inventory issue
- rotate all secrets reachable from that environment, including cloud, source-control, registry, Kubernetes, database, and AI-provider credentials
- remove
litellm_init.pthand investigate any systemd or user-level persistence before trusting the host again - review package publishing, repository writes, and CI configuration changes that occurred after the exposure window
- re-scope March exposure with the August dataset in mind, especially if the original response only removed the package and never rotated secrets
The key lesson from the August LiteLLM follow-up is simple: short-lived package compromise windows do not stay short once the malicious code reaches a runner that can publish, deploy, or talk to model infrastructure. The article-worthy change in the last three days is not a new bad version number. It is the public evidence that many teams still underestimated what those two old version numbers could reach.
From research to remediation
Check whether this pattern exists in your codebase
Turn this research into a remediation workflow. Scan dependencies and package manifests for similar supply-chain risk, then prioritize fixes with reachability context.
References
- LiteLLM: Security Update - Suspected Supply Chain Incident
- LiteLLM issue #24518: full timeline and status for the compromised PyPI packages
- CloudSEK: 2,500+ Companies and 434,000 CI/CD Pipelines Exposed in the Largest AI Supply Chain Breach of 2026
- StepSecurity: Team PCP Stole 78,330 Secrets From 2,186 Organizations
- SecurityWeek: Over 2,500 Organizations Impacted by LiteLLM Supply Chain Attack
- Ars Technica: Terabytes of credentials leaked in massive supply-chain attack
- Cycode: LiteLLM Supply Chain Attack - What Happened and How to Respond
- Openwall oss-security: backdoor in litellm version 1.82.7