Commissioned, Curated and Published by Russ. Researched and written with AI.


What’s New This Week

On March 24, 2026, malicious LiteLLM packages were detected on PyPI and quarantined within approximately three hours. This is the same TeamPCP campaign that started with the Trivy GitHub Actions compromise on March 19.


Changelog

DateSummary
25 Mar 2026Initial article covering the incident, the Trivy cascade, payload analysis, and remediation steps.

What happened

At 10:39 UTC on March 24, 2026, malicious version 1.82.7 of the LiteLLM Python library was published to PyPI. Thirteen minutes later, a second version, 1.82.8, followed with an escalated delivery mechanism. PyPI quarantined the package at approximately 11:25 to 13:38 UTC – sources give slightly different timestamps for the quarantine, depending on which stage is measured. Both versions are gone. The package itself remained accessible at safe versions.

The safe version is anything at or below 1.82.6. If you have 1.82.7 or 1.82.8 installed anywhere, assume the environment is fully compromised and rotate credentials before doing anything else.

What LiteLLM is and why it matters

LiteLLM, maintained by BerriAI, is an open-source Python library that provides a single unified interface to over 100 large language model providers. You write code against one API, and LiteLLM handles routing to OpenAI, Anthropic, Google, AWS Bedrock, Azure, Ollama, or wherever your models actually live. That’s the value proposition: one abstraction layer, every provider.

This is not a niche tool. According to BleepingComputer and Snyk, LiteLLM has approximately 3.4 million downloads per day and over 95 million in the past month. Wiz’s cloud environment data shows LiteLLM present in 36% of cloud environments they monitor. If you are building anything serious with large language models, there is a strong chance LiteLLM is in your stack – in your local development environment, in your Docker containers, and almost certainly in your CI/CD pipeline.

That last point matters. CI/CD is where this gets bad.

The Trivy connection

This attack did not begin with LiteLLM.

In late February 2026, a threat actor later identified as TeamPCP (also tracked as PCPcat, Persy_PCP, ShellForce, DeadCatx3) exploited a misconfiguration in Trivy’s GitHub Actions environment. Trivy is the open-source vulnerability scanner maintained by Aqua Security. The misconfiguration allowed a malicious pull request to trigger a pull_request_target workflow that exfiltrated a privileged access token for the aqua-bot account.

On March 19, 2026, attackers used those stolen credentials to publish malicious Trivy version v0.69.4. Critically, they also rewrote existing version tags in the trivy-action repository to point to the malicious release. Because most CI/CD pipelines pin to a version tag rather than a specific commit hash, pipelines that thought they were running a known-good Trivy version were silently executing the attacker’s code.

That malicious Trivy Action ran in LiteLLM’s CI/CD pipeline. It harvested LiteLLM’s PyPI publishing token – stored as an environment variable in the project’s GitHub repo – and exfiltrated it. According to Krrish Dholakia, CEO of BerriAI, the company’s PyPI accounts had two-factor authentication enabled. The token, not the password, was the entry point. Five days after the Trivy compromise, that token was used to push malicious packages to PyPI.

TeamPCP also hit the Checkmarx KICS GitHub Action in the same campaign window. LiteLLM is the third major victim in a single continuous operation.

What the malicious code did

The two versions differed slightly in how they delivered their payload.

Version 1.82.7 injected a base64-encoded payload into litellm/proxy/proxy_server.py. The malicious code executed whenever that module was imported – which happens whenever LiteLLM is used as a proxy server, or whenever any code imports from that module path.

Version 1.82.8 went further. It included a file named litellm_init.pth placed in the Python environment’s site-packages directory. Python automatically processes every .pth file in that directory on interpreter startup, before any user code runs. The malicious .pth file executed a double base64-encoded payload via subprocess on every single Python invocation, regardless of whether LiteLLM was imported at all. Install it once, and every subsequent python command on that machine runs attacker code.

Once executing, the payload performed the same data collection seen in the KICS and Trivy compromises. Targets included environment variables (API keys, tokens), SSH keys, AWS credentials, GCP credentials, Azure credentials, Kubernetes configuration, CI/CD pipeline secrets, Docker configuration, database credentials, and cryptocurrency wallets. The collected data was encrypted with AES-256, with the encryption key further encrypted using an embedded RSA public key, then exfiltrated to an attacker-controlled domain: models.litellm.cloud for version 1.82.8, checkmarx.zone for 1.82.7.

The exfiltration domain models.litellm.cloud was registered on March 23 – the day before the attack – and was deliberately designed to blend in with legitimate LiteLLM infrastructure.

The payload also included Kubernetes-specific persistence and a worm component seen in earlier TeamPCP operations. In environments without a Kubernetes cluster or running outside certain geographic configurations, it installs a backdoor. In environments it detects as being configured for Iran, it deploys a wiper.

TeamPCP has claimed approximately 500,000 data exfiltrations, though BleepingComputer notes that many of these are likely duplicates, and independent verification is not available. Sonatype’s automated tooling detected and blocked the malicious versions within seconds of publication.

The blast radius question

The “95M monthly downloads” number gets repeated in most coverage. It deserves some context.

95 million is the monthly download count for the entire LiteLLM package, across all versions, including automated CI/CD pulls and dependency resolution. It reflects reach, not exposure. The malicious versions were live for approximately three hours on a single day. The realistic question is how many of those 95 million monthly downloads happened to install 1.82.7 or 1.82.8 during that window – and whether they ran code that triggered the payload.

Automated dependency resolution is the concern here. If your CI/CD pipeline does a fresh pip install litellm on every build, and it ran a build during those three hours, you got the malicious version. If you pin to a specific version in your requirements file and that version was 1.82.7 or 1.82.8, you are affected on every subsequent install.

For most teams using a stable pinned version below 1.82.7, there is no exposure. For teams with unpinned dependencies, auto-update pipelines, or builds that ran on March 24 between roughly 08:30 and 13:38 UTC, there is a real question to answer.

The credential theft profile is also worth considering. In a CI/CD environment, the credentials available to a running process are typically the most powerful credentials in the organisation: deployment keys, cloud provider credentials, package signing tokens. A single compromised build runner can hand an attacker keys to production infrastructure.

What to do

Check your installed version:

pip show litellm

If any environment shows 1.82.7 or 1.82.8, treat it as compromised.

Check for the persistence file:

find / -name "litellm_init.pth" 2>/dev/null

If it exists, delete it, then audit every credential the affected Python environment had access to.

Rotate any credentials that were in scope for an affected build runner or development environment during March 24, 2026. That means: AWS access keys, GCP service account keys, Azure credentials, PyPI tokens, GitHub tokens, Kubernetes service account tokens, any API keys set as environment variables, and SSH keys accessible to the process.

If you are running CI/CD pipelines, check your build logs for jobs that ran during the window and pulled LiteLLM without version pinning. If any match, assume the build runner environment was fully read by the payload.

BerriAI has deleted all their PyPI publishing tokens and is reviewing their publishing setup – with a move toward trusted publishing via JWT tokens under consideration.

The AI tooling supply chain pattern

This is the third major supply chain attack against AI tooling infrastructure in March 2026. Trivy. CanisterWorm spreading through npm packages. Now LiteLLM.

These are not coincidental. TeamPCP is systematically working through the dependency graph of the AI development ecosystem – security scanners, CI/CD tools, foundational libraries. The attack surface is wide because the tooling ecosystem assembled very quickly. LiteLLM is three years old and in 36% of cloud environments. The security hygiene around its publishing pipeline – environment variable storage of PyPI tokens, reliance on tag-pinned GitHub Actions – is representative of how most open-source projects at this scale operate.

There is a structural problem here. The projects that form the invisible infrastructure of AI development are maintained by small teams, often bootstrapped, with limited resources to invest in supply chain hardening. Version tag pinning instead of commit hash pinning is the norm. Secrets stored as environment variables rather than via OIDC trusted publishing is the norm. These are not oversights – they are the pragmatic defaults for projects moving fast.

TeamPCP is not discovering novel vulnerabilities. They are exploiting known patterns at scale. The Trivy misconfiguration (pull_request_target workflows with write access) is a well-documented GitHub Actions footgun that has been warned about for years. The LiteLLM token was extracted because it was in scope for the compromised action.

The lesson is not that these teams are careless. The lesson is that one compromised node in a dependency graph can propagate damage several hops downstream, and the downstream victims had no way to know. LiteLLM was not breached through anything they did wrong. They were breached because a tool they included in their CI/CD pipeline was compromised first.

Supply chain security is not about hardening your own perimeter. It is about understanding that the perimeter now includes every dependency your build system touches.