# LiteLLM Supply Chain Attack: How to Check If You're Affected

URL: https://blog.bokvi.com/blog/litellm-supply-chain-attack/
Published: 2026-03-25
Tags: security, python, supply-chain, litellm, pypi

On March 24, 2026, two malicious versions of the popular [LiteLLM](https://github.com/BerriAI/litellm) Python package — v1.82.7 and v1.82.8 — were published to PyPI. The compromised packages contained a multi-stage credential stealer that exfiltrates SSH keys, cloud tokens, environment variables, and more. According to [Snyk's analysis](https://snyk.io/articles/poisoned-security-scanner-backdooring-litellm/), v1.82.7 went up at 10:39 UTC and v1.82.8 at 10:52, and PyPI quarantined the package about three hours after the first. [LiteLLM's own update](https://docs.litellm.ai/blog/security-update-march-2026) puts it at about 40 minutes. Either way, given LiteLLM's ~3.4 million daily downloads and its role as a transitive dependency in many AI tools, the blast radius is significant.

This post summarizes what happened, how to validate whether you're affected, and what to do if you are.

## What happened

The attack was carried out by a threat group known as **TeamPCP**. The chain of events:

1. **March 19** — TeamPCP compromised Aqua Security's **Trivy** vulnerability scanner by rewriting Git tags in the `trivy-action` GitHub Action to point to a malicious release carrying a credential-harvesting payload.
2. **March 23** — The same infrastructure was used to compromise Checkmarx **KICS** GitHub Actions.
3. **March 24** — LiteLLM's CI/CD pipeline ran Trivy as part of its build process without a pinned version. The compromised Trivy action exfiltrated the `PYPI_PUBLISH` token from the GitHub Actions runner, which was then used to publish malicious LiteLLM versions directly to PyPI — bypassing the normal release process entirely.

The malicious versions included:

- **v1.82.7**: malicious payload injected into `proxy_server.py`
- **v1.82.8**: same payload plus a `litellm_init.pth` file — a Python path configuration file that executes automatically on **every Python process startup**, not just when LiteLLM is imported

## Why this is particularly dangerous

LiteLLM sits between applications and multiple LLM providers (OpenAI, Anthropic, Google, etc.), which means it typically has access to API keys, environment variables, and sensitive configuration data. It's also a transitive dependency for many AI agent frameworks, MCP servers, and LLM orchestration tools.

The `.pth` file mechanism in v1.82.8 is especially nasty — it runs on every Python process in the environment, regardless of whether the script uses LiteLLM. Any Python script, test runner, linter, or tool invoked in an environment where the compromised package was installed would silently trigger the credential harvester.

The researcher who first discovered the attack found it because their **Cursor IDE** pulled in LiteLLM through an MCP plugin as a transitive dependency.

## The malware's three stages

The payload operates in three stages:

1. **Orchestrator** — Collects and encrypts stolen data, sends it to a remote C2 server (using the domain `models.litellm.cloud`, which is **not** an official LiteLLM domain)
2. **Credential harvester** — Scans the system for SSH keys, cloud credentials (AWS, GCP, Azure), Kubernetes secrets, `.env` files, database configs, crypto wallets, and system logs. Can also move laterally by deploying privileged pods across Kubernetes nodes.
3. **Persistence** — Installs a systemd service (`sysmon.service`) that regularly contacts a remote server, downloads new payloads, and maintains long-term access

## Am I affected?

**You may be affected if** (per [LiteLLM's security update](https://docs.litellm.ai/blog/security-update-march-2026)):

- You installed or upgraded LiteLLM via pip on March 24, 2026, between 10:39 UTC and 16:00 UTC. That window is wider than either estimate of how long the versions were live, so check all of it.
- You ran `pip install litellm` without pinning a version and received v1.82.7 or v1.82.8
- You built a Docker image during this window with an unpinned `pip install litellm`
- A dependency in your project pulled in LiteLLM as a transitive, unpinned dependency

**You are NOT affected if:**

- You were running the official LiteLLM Proxy Docker image
- You had LiteLLM pinned to v1.82.6 or earlier
- You didn't install or upgrade any Python packages on March 24

## How to check

### 1. Check your installed version

```bash
pip show litellm
```

If it shows version `1.82.7` or `1.82.8`, you're compromised.

### 2. Search for the malicious .pth file

```bash
# Check uv caches
find ~/.cache/uv -name "litellm_init.pth" 2>/dev/null

# Check pip caches
find ~/.cache/pip -name "litellm_init.pth" 2>/dev/null

# Check all virtualenvs and site-packages
find / -name "litellm_init.pth" 2>/dev/null
```

### 3. Check for persistence mechanisms

```bash
# Systemd backdoor
ls -la ~/.config/sysmon/sysmon.py
ls -la ~/.config/systemd/user/sysmon.service
systemctl --user status sysmon.service 2>/dev/null

# Kubernetes (if applicable)
kubectl get pods -n kube-system | grep node-setup
```

### 4. Check CI/CD pipelines

Review your CI/CD logs for any `pip install litellm` activity on March 24. Check Docker build logs, GitHub Actions runs, and any automated deployment pipelines that might have pulled in the package.

### 5. Check for outbound connections

Review network logs for connections to:

- `models.litellm.cloud` (attacker C2, not an official LiteLLM domain)
- `checkmarx.zone` (related C2 from the KICS compromise)

## What to do if you're affected

Simply removing the package is **not sufficient**. The malware establishes persistence and may have already deployed additional payloads.

1. **Remove the package and purge caches**
   ```bash
   pip uninstall litellm
   pip cache purge
   rm -rf ~/.cache/uv
   ```

2. **Remove persistence mechanisms**
   ```bash
   rm -f ~/.config/sysmon/sysmon.py
   rm -f ~/.config/systemd/user/sysmon.service
   systemctl --user disable sysmon.service 2>/dev/null
   ```

3. **Rotate ALL credentials** that were present on the affected machine:
   - SSH keys
   - Cloud provider credentials (GCP ADC, AWS access keys, Azure tokens)
   - Kubernetes configs
   - API keys in `.env` files
   - Database passwords
   - Crypto wallet keys
   - CI/CD tokens (GitHub, GitLab, etc.)

4. **Audit Kubernetes clusters** for unauthorized pods, especially in `kube-system` namespace

5. **Consider rebuilding from a known clean state** — this is the safest option, especially for production systems

## Lessons learned

This attack highlights several systemic issues in the Python/AI ecosystem:

- **Transitive dependencies are a huge attack surface.** You may never have run `pip install litellm`, but if anything in your dependency tree pulls it in unpinned, you're exposed.
- **Pin your dependencies.** Use lockfiles (`pip-compile`, `uv lock`, `poetry.lock`) and pin versions in Docker builds.
- **Security tools can be attack vectors.** The irony here is thick — Trivy, a vulnerability scanner, was the entry point that led to the LiteLLM compromise.
- **AI tooling is becoming a high-value target.** Packages like LiteLLM sit at a privileged position with access to multiple API keys and cloud credentials, making them attractive targets.
- **`.pth` files are a dangerous Python mechanism.** They execute on every interpreter startup with no import required — a footgun that the Python packaging ecosystem should probably revisit.

## Further reading

- [LiteLLM official security update](https://docs.litellm.ai/blog/security-update-march-2026)
- [Snyk's detailed analysis of the attack chain](https://snyk.io/articles/poisoned-security-scanner-backdooring-litellm/)
- [Wiz blog on TeamPCP and LiteLLM](https://www.wiz.io/blog/threes-a-crowd-teampcp-trojanizes-litellm-in-continuation-of-campaign)
- [FutureSearch's initial discovery write-up](https://futuresearch.ai/blog/litellm-pypi-supply-chain-attack/)
- [GitHub issue #24512](https://github.com/BerriAI/litellm/issues/24512) (the original report, which was closed by attackers and flooded with bot comments)