LiteLLM Supply Chain Breach: How a Compromised Scanner Delivered a Backdoor

Attackers used a poisoned Trivy CI tool to inject a credential-stealing backdoor into the widely used LiteLLM Python package. This post breaks down what happened, how it worked, and lessons for developers.

Catch Credential Theft at Runtime
  • March 25, 2026

LiteLLM was recently hit by a sophisticated supply-chain attack. Two backdoored versions (1.82.7 and 1.82.8) were published to PyPI by the threat group TeamPCP after stealing the maintainer’s credentials. The attackers had first compromised Trivy (an open-source security scanner) in LiteLLM’s CI/CD pipeline, harvesting a PYPI_PUBLISH token.

The malicious releases remained live for roughly three hours before PyPI quarantined them. Despite this short window, many systems were at risk: LiteLLM sees about 3.4 million downloads per day (over 95 million per month). In effect, a poisoned CI tool transformed a trusted library into a malware dropper.

Trivy Breach Sparks LiteLLM Attack

Analysis shows the chain of attack began days earlier with Trivy’s repositories. On March 19, TeamPCP exploited a GitHub Actions workflow in Trivy to push malicious code into many release tags and even publish a tainted Trivy binary (v0.69.4). LiteLLM’s build pipeline, which ran Trivy without pinning its version, ended up using the compromised scanner.

The poisoned Trivy exfiltrated the LiteLLM project’s PyPI publishing token to the attackers. Armed with these legitimate credentials, TeamPCP uploaded the backdoored LiteLLM packages on March 24. In short, a security tool meant to protect the codebase became the launchpad for the breach.

Two Backdoored LiteLLM Releases: What Was Hidden

The malware authors used two different sneaky methods to hide their code. In version 1.82.7, they injected a base64-encoded payload into the file litellm/proxy/proxy_server.py. This code ran whenever LiteLLM’s proxy mode was used. In version 1.82.8, they went further by adding a litellm_init.pth file at the root of the package. Python automatically processes .pth files at interpreter startup, so this backdoor fired in every Python process (even if LiteLLM was never explicitly imported).

Importantly, these malicious additions were baked into the package at build-time with the attacker’s credentials. As a result, pip’s normal integrity checks and hash verifications passed without error. In other words, the releases appeared legitimate to automated scans the malware snuck in under the radar.

LiteLLM Supply Chain Compromise
3.4M
Daily Downloads
3 hrs
Exposure Window
100%
Integrity Bypass
The Infection Chain
Trivy v0.69.4 weaponization by TeamPCP enabled PYPI_PUBLISH token exfiltration for malicious LiteLLM releases.
v1.82.7: Proxy Injection
v1.82.8: .pth Startup Hook
Data Exfiltration
SSH & Cloud Credentials
K8s Cluster Secrets
Crypto Wallet Seeds
Double-Layer Encryption
AES-256 + 4096-bit RSA secure exfiltration.
Persistence
Privileged K8s Alpine pods & systemd.
XCITIUM THREAT LABS

Three-Stage Malware: Harvest, Exfiltrate, Persist

Once activated, the LiteLLM backdoor performed a three-stage attack. First it harvested data from the host, then encrypted and exfiltrated it, and finally persisted for ongoing access. For example, the script collected:

  • SSH keys and certificates (from ~/.ssh and /etc/ssh)
  • All cloud provider credentials (AWS keys, GCP service account files, Azure tokens, etc.)
  • Kubernetes configs and secrets (kubeconfig files, service account tokens)
  • Environment files and CI/CD configs (e.g. .env, Jenkins or Travis configs)
  • Docker registry credentials and system metadata (hostname, network routes)
  • Even cryptocurrency wallet files and seed phrases.

Next, the malware encrypted the data before sending it out. It generated a random AES-256 session key, used it to encrypt the collected files, then encrypted that AES key with a hardcoded 4096-bit RSA public key. Everything was packaged into an archive tpcp.tar.gz and POSTed to https://models.litellm.cloud/ (a fake-sounding domain the attackers had just registered). Even if intercepted, the double encryption meant only the attackers could decrypt the exfiltrated trove.

Finally, the code established a backdoor for long-term access. It wrote a malicious Python script as ~/.config/sysmon/sysmon.py (or in /root/.config/…) and created a systemd user service called “sysmon.service” to run it. This service polled another attacker-controlled site (checkmarx.zone/raw) a few minutes at a time to download and execute new commands.

If the malware detected Kubernetes credentials on the system, it would launch privileged Alpine Linux pods on all nodes within the Kubernetes cluster to mount the host filesystem and install itself. This ensured the attacker would maintain access even if the system were rebooted or the LiteLLM package were uninstalled.

Impact and Response

PyPI was able to quickly block the vulnerable versions, and LiteLLM developers were able to rapidly rotate all the keys and accounts. However, any environment that installed LiteLLM versions 1.82.7 or 1.82.8 during this window was at extreme risk. The vulnerable versions of the packages have now been deleted (safe versions are ≤1.82.6).

LiteLLM is a popular and important “AI gateway” package, and it deals with dozens of API keys and tokens. The single weak point of an unpinned Trivy scanner led to this cascade of compromise.

Lessons and Defense Strategies

  • Pin and verify dependencies. It is not recommended to pull in the latest version of tools without pinning. Even if tools are trustworthy, they can become backdoors if their versions are not vetted. Tools with automated ‘latest’ tag imports should be carefully scrutinized.
  • Be suspicious of startup hooks. The .pth file trick meant malware would execute on every Python startup. Generally speaking, Python initialization files should be used with caution. Python initialization files have a tendency to overextend an app’s scope.
  • Isolate sensitive assets. It is possible to avoid putting critical secrets in general-purpose dependencies. It would be wise to run language model code in a separate process/container so that if a library is compromised, it cannot easily sweep up arbitrary credentials.

Conclusion: When the Security Tool Becomes the Supply Chain Threat

The LiteLLM breach exposes a hard reality of modern software delivery. The attacker did not compromise the package first. They compromised the scanner that the package trusted. A poisoned Trivy binary exfiltrated the project’s PyPI publishing token, then legitimate credentials were used to publish backdoored LiteLLM releases to PyPI. The result was not a fake package. It was a trusted package turned into a malware dropper. 

Why This Threat Matters

This is what makes supply chain attacks so dangerous. Every signal looked legitimate.

  • The malicious versions were signed and published with valid maintainer credentials
  • Pip integrity checks and hash verification passed without error
  • One build used a .pth startup hook, so the backdoor executed in every Python process
  • The malware harvested SSH keys, cloud credentials, Kubernetes secrets, CI configs, and wallet seeds, then established persistence with systemd and privileged Kubernetes pods 

Once trusted code is poisoned upstream, downstream defenders inherit the compromise instantly.

Why Organizations Are Vulnerable

This incident was not caused by one reckless decision. It was caused by normal engineering behavior.

  • Security tools were consumed without strict version pinning
  • CI pipelines trusted automated “latest” dependencies
  • High-value secrets were reachable from general-purpose build environments
  • Startup hooks and package initialization paths were not treated as high-risk execution surfaces 

That is why modern supply chain attacks are so effective. They weaponize the trust that development pipelines are built on.

Where Xcitium Changes the Outcome

If you have Xcitium, this attack would NOT succeed.

  • Xcitium Advanced EDR stops the backdoored package at execution, so malicious startup hooks, credential harvesting, persistence, and follow-on command retrieval fail before they can impact the real system
  • Code can run without being able to cause damage, which breaks the attacker’s path from poisoned dependency to operational compromise

The attacker may poison the package, but they still need execution to win.

Trust the Package Less, Control Execution More

Pin dependencies. Isolate sensitive assets. Treat CI tooling like production infrastructure. Then enforce runtime controls that keep a trusted package from becoming a trusted breach.

Like what you see? Share with a friend.

Move Away From Detection With Patented Threat Prevention Built For Today's Challenges.

No one can stop zero-day malware from entering your network, but Xcitium can prevent if from causing any damage. Zero infection. Zero damage.

Book a Demo