Supply Chain Attacks in 2026: Axios 1.14.1, LiteLLM, and How to Protect Your Projects
Table of Contents
- Two Attacks, One Week
- Axios 1.14.1 — A RAT Inside Your HTTP Client
- LiteLLM 1.82.7 — Your AI Proxy Was Stealing Your Secrets
- The Pattern: TeamPCP and Chained Attacks
- Am I Affected?
- How to Protect Your Projects Today
- What Lockfiles Actually Protect You From (and What They Don’t)
- The Uncomfortable Truth
Two Attacks, One Week
Between March 24 and March 31, 2026, two of the most downloaded packages in the JavaScript and Python ecosystems were compromised at the source:
- LiteLLM (Python, ~95M monthly downloads) — credential stealer with Kubernetes lateral movement
- Axios (npm, ~83M weekly downloads) — full RAT (Remote Access Trojan) with platform-specific payloads
These weren’t typosquatting attacks. These weren’t malicious forks. The official packages on the official registries were publishing malware. If you ran npm install or pip install at the wrong time, you were compromised.
I audited my own projects after these incidents. Here’s what I found and what I’m doing about it.
Axios 1.14.1 — A RAT Inside Your HTTP Client
What Happened
On March 31, 2026 at 00:21 UTC, a malicious version of Axios (1.14.1) was published to npm. 39 minutes later, 0.30.4 followed — targeting users still on the legacy 0.x branch.
The attacker had compromised the npm account of Axios’s primary maintainer (jasonsaayman), changed the email to a ProtonMail address, and published directly via npm CLI — bypassing the GitHub Actions CI/CD pipeline entirely.
The Payload
The attack was operationally sophisticated. Axios 1.14.1 added a phantom dependency called plain-crypto-js that never appeared in the actual code. Its only purpose was a postinstall hook.
The dropper (setup.js) used two-layer obfuscation: an XOR-decoded string array (key: OrDeR_7077) plus base64. It contacted a C2 server at sfrclak.com:8000 and downloaded platform-specific RATs:
| OS | Payload | Persistence |
|---|---|---|
| macOS | AppleScript → curl → RAT binary | /Library/Caches/com.apple.act.mond (mimics Apple daemon) |
| Windows | VBScript → PowerShell (copied as wt.exe) → RAT | %PROGRAMDATA%\wt.exe |
| Linux | Shell → Python RAT | /tmp/ld.py via nohup |
After deploying the RAT, the dropper deleted itself and replaced package.json with a clean stub — destroying forensic evidence.
Detection and Response
Socket detected plain-crypto-js automatically 6 minutes after publication. The community reported it in GitHub issue #10604. npm removed the malicious versions within hours.
But the damage was already visible: the other Axios collaborator (DigitalBrainJS) publicly stated: “Since his permissions are higher than mine… Whatever I fix, he will ‘fix’ after me.” At the time of writing, the maintainers had not fully recovered control of the project.
Exposure window: a few hours. But for a package with 83 million weekly downloads, a few hours is millions of installs.
LiteLLM 1.82.7 — Your AI Proxy Was Stealing Your Secrets
What Happened
On March 24, 2026, versions 1.82.7 and 1.82.8 of LiteLLM were published to PyPI with malicious code injected into proxy_server.py.
The attack was part of a larger campaign by a group called TeamPCP. Their chain:
- First, they compromised Trivy (Aqua Security’s vulnerability scanner — a GitHub Action)
- Through compromised Trivy, they stole PyPI credentials from a LiteLLM maintainer
- With those credentials, they published directly to PyPI, bypassing BerriAI’s official CI/CD
The Payload
This was a 3-stage credential stealer, far more dangerous than the Axios RAT:
Stage 1 — Credential Harvesting: collected 50+ categories of secrets including SSH keys, environment variables, AWS/GCP/Azure credentials, Kubernetes configs, database passwords, .gitconfig, shell history, and even cryptocurrency wallets. If running in cloud, it scraped instance metadata endpoints (EC2, GKE).
Stage 2 — Kubernetes Lateral Movement: a toolkit to move laterally within K8s clusters, capable of compromising entire clusters.
Stage 3 — Persistent Backdoor: remote code execution that survived restarts.
The clever part: version 1.82.8 included a file called litellm_init.pth that executed automatically on every Python interpreter start — you didn’t even need to import litellm. Just having it installed was enough.
All stolen data was exfiltrated to models.litellm.cloud — a domain controlled by the attacker that mimics the official litellm.ai.
Detection and Response
The community detected the compromise within ~5.5 hours. BerriAI acknowledged the attack, removed the affected versions from PyPI, and paused all new releases until completing a full supply chain review.
Stanford’s DSPy project opened issue #9500 to notify their users, since DSPy depends on LiteLLM.
The Pattern: TeamPCP and Chained Attacks
TeamPCP didn’t attack LiteLLM in isolation. They executed a cascading supply chain campaign across 5 ecosystems:
Trivy (security scanner) → compromised
→ LiteLLM (AI proxy) → compromised via stolen PyPI creds
→ Telnyx (communications) → next target
Checkmarx (SAST tool) → compromised
KICS (IaC scanner) → compromised
Each compromise gave them credentials for the next one. Security tools themselves became the attack vector — the tools you use to scan for vulnerabilities were the ones delivering malware.
The Axios attack appears to be a separate operation (direct account compromise, not chained), but the timing — one week apart — is notable. Whether coordinated or not, March 2026 demonstrated that supply chain attacks on tier-1 packages are no longer theoretical.
Am I Affected?
Axios (npm)
# Check your lockfile
grep '"axios"' package-lock.json
# or
grep 'axios@' yarn.lock pnpm-lock.yaml
Affected versions: 1.14.1 and 0.30.4 only. If your lockfile shows any other version, you’re safe. If you installed between March 31 00:21 UTC and the removal (a few hours later), check.
Also search for the phantom dependency:
ls node_modules/plain-crypto-js 2>/dev/null && echo "COMPROMISED" || echo "Clean"
LiteLLM (Python)
pip show litellm 2>/dev/null | grep Version
# Also check for the persistence file
find / -name "litellm_init.pth" 2>/dev/null
Affected versions: 1.82.7 and 1.82.8. If you installed between March 24 10:39 UTC and ~16:00 UTC, check.
If You’re Affected
This is not a “update and move on” situation. Assume the machine is compromised.
- Don’t just update — rebuild the environment from scratch
- Rotate ALL secrets: npm tokens, AWS keys, SSH keys, database passwords, CI/CD secrets, API keys
- Audit Kubernetes if the environment had cluster access
- Check network logs for connections to
sfrclak.com(Axios) ormodels.litellm.cloud(LiteLLM) - Block C2 IPs:
142.11.206.73(Axios)
How to Protect Your Projects Today
None of these are silver bullets. Supply chain attacks exploit trust, and trust is the foundation of package managers. But you can reduce your attack surface:
1. Pin exact versions — always
// Bad
"axios": "^1.14.0"
// Good
"axios": "1.14.0"
The ^ prefix is what makes npm install pick up 1.14.1 automatically. Without it, you only get updates when you decide.
2. Use lockfiles and commit them
Your package-lock.json, yarn.lock, or pnpm-lock.yaml is your defense against auto-upgrades. Commit it. Always. In CI, use npm ci (not npm install) to respect the lockfile strictly.
3. Disable postinstall scripts for untrusted packages
The Axios attack relied entirely on a postinstall hook. You can block this:
# .npmrc
ignore-scripts=true
Then manually run scripts only for packages you trust:
npm rebuild <trusted-package>
4. Audit regularly
npm audit # npm
pip-audit # Python (install: pip install pip-audit)
5. Use Socket, Snyk, or similar in CI
These tools detect behavioral anomalies in packages (network calls, filesystem access, obfuscation) — things that npm audit misses because they’re not CVEs yet.
6. Review what your CI has access to
Both attacks exploited CI/CD credentials. If your GitHub Actions workflow has npm/PyPI tokens:
- Use OIDC trusted publishing instead of long-lived tokens
- Restrict token permissions to the minimum
- Enable 2FA on your registry accounts (npm, PyPI)
7. Auto-merge only security patches
If you use Dependabot, configure it to open PRs for all updates but only auto-merge security patches. Set up a GitHub Actions workflow that checks if the PR has a ghsa-id (GitHub Security Advisory) before approving and merging:
# .github/workflows/dependabot-auto-merge.yml
name: Auto-merge Dependabot security patches
on: pull_request
permissions:
contents: write
pull-requests: write
jobs:
auto-merge:
if: github.actor == 'dependabot[bot]'
runs-on: ubuntu-latest
steps:
- name: Fetch Dependabot metadata
id: metadata
uses: dependabot/fetch-metadata@v2
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Auto-merge security updates only
if: steps.metadata.outputs.ghsa-id != ''
run: gh pr merge --auto --squash "$PR_URL"
env:
PR_URL: ${{ github.event.pull_request.html_url }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
This way, version bumps stay as open PRs for you to review manually — only verified security fixes get merged automatically. If the Axios attack had been a version bump PR, it would have sat there waiting for your approval instead of being auto-merged.
8. Don’t be the guinea pig
When installing a new package, don’t blindly grab the latest version. Check the changelog. Pick a recent version that’s been out for days or weeks with no incident reports. If the latest release dropped 20 minutes ago, let someone else find out if it’s compromised. Both Axios 1.14.1 and LiteLLM 1.82.7 were detected within hours — if you had waited a day, you would have never installed them.
9. Monitor for account compromises
Subscribe to security advisories for your critical dependencies. Follow the #security channels in your ecosystem and enable GitHub’s security alerts for your repositories.
10. Pin GitHub Actions to commit SHAs, not tags
🔄 Update (March 31, 2026 — 20:13 UTC-3): This tip was added after further analysis of how TeamPCP exploited mutable Git tags in Trivy’s GitHub Action.
Tags in Git are mutable by default. Anyone with push access can move a tag to point to a completely different commit. TeamPCP exploited exactly this — they force-pushed 76+ tags in trivy-action to malicious commits. Every pipeline referencing those actions by tag silently started executing the attacker’s code with no visible change on GitHub.
# Vulnerable — tag can be moved to a malicious commit
- uses: actions/checkout@v4
# Safe — immutable reference to a specific commit
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
After learning this, I audited my own workflows and found 5 actions pinned to tags across two projects. I replaced all of them with SHA references the same day. It took 10 minutes.
This only applies to GitHub Actions (.github/workflows/*.yml). npm/pip use different version resolution — lockfiles and version pinning handle those.
What Lockfiles Actually Protect You From (and What They Don’t)
Lockfiles protect you if: you already have a clean install and you use npm ci in CI. The lockfile pins the exact resolved version, so a compromised new version won’t be pulled.
Lockfiles don’t protect you if: you run npm install (which updates the lockfile), or if you’re setting up a new project, or if the compromised version was published before your first install.
Lockfiles don’t protect you from: a compromised version that was published before you created the lockfile. If 1.14.1 existed when you first ran npm install, it’s in your lockfile forever until you update.
The real protection is awareness + pinning + auditing + behavioral scanning. No single tool solves this.
The Uncomfortable Truth
Supply chain attacks are getting more sophisticated, not less. The Axios attacker used anti-forensics (self-deleting dropper). TeamPCP chained compromises across security tools. Both bypassed official CI/CD pipelines by going directly to the registry.
The open source ecosystem runs on trust and volunteer maintainers. When a single maintainer’s credentials are compromised, millions of projects are exposed. There’s no easy fix for this — it’s a systemic issue.
What you can do is reduce your exposure: pin versions, audit regularly, disable scripts, use behavioral scanning, and assume that any dependency could be compromised at any time.
Because in March 2026, two of them were.
My projects were not affected — I checked. Axios was pinned at an earlier version in my lockfiles, and I don’t use LiteLLM. But the margin was thin. If I had run npm update that morning, this would be a very different post.