TL;DR — In March 2026, an attacker published
axios 1.14.1and0.30.4with a RAT hidden in a phantom dependency (plain-crypto-js).npm audit, Snyk, and Dependabot all said clean. Dependency Guardian fired 5 behavioral detectors and blocked the install. This post walks through exactly what fired and why.
Axios has 100 million weekly downloads. For about three hours in March 2026, every one of those installs came with a RAT.
npm audit said it was fine. Snyk said it was fine. Dependabot didn't raise a flag. The attacker had stolen the real maintainer's credentials, so even npm's provenance checks passed. Every tool in the standard security stack looked at the compromised package and said: clean.
The only way to catch this kind of attack is to stop asking "who published this?" and start asking "what does this code do?"
Axios supply chain attack timeline: what happened in March 2026
An attacker social-engineered Axios maintainer Jason Saayman. Weeks of fabricated collaboration, patient enough to eventually hijack a browser session. Two malicious versions went up within hours: axios 1.14.1 and axios 0.30.4. No matching GitHub releases. No CI artifacts. The code existed only on npm.
The payload wasn't in Axios itself. The attacker slipped a single new dependency into Axios's package.json: plain-crypto-js. Brand new. Zero downloads. Zero GitHub presence. A name chosen to pass a quick glance as a crypto-js fork.
Inside was a platform-specific RAT. macOS got AppleScript execution dropping a binary disguised as an Apple system service. Windows got PowerShell running with a hidden window. Linux got a Python reverse shell. All three beaconed to a C2 server every 60 seconds, with requests disguised as legitimate npm traffic.
After execution, the malware deleted itself and restored a clean package.json. It destroyed the evidence that the dependency had ever existed. That self-cleaning behavior is what made incident response so painful for teams that had already installed the compromised version.
OpenAI disclosed that the attack reached their macOS signing pipeline, forcing a full certificate rotation.
Why npm audit, Snyk, and Dependabot missed the axios compromise
npm audit checks your packages against a database of known-bad versions. Snyk and Dependabot do the same thing with different databases. The mechanism is identical: has someone already reported a problem with this exact version?
Nobody had. The malicious code was original. No CVE. No advisory. Nothing in any database to match.
These tools are retrospective by design. They tell you about attacks someone else already discovered. When the attack just went live, all of them return clean. Not because they're broken. Because they weren't built for this.
How Dependency Guardian detected plain-crypto-js and blocked the install
Dependency Guardian doesn't check databases. It reads the code. On plain-crypto-js, five independent signals fire:
- Install script execution: the package runs code during
npm installvia a postinstall hook - Obfuscated code: reversed Base64 combined with an XOR cipher, distinct from bundler output
- Network exfiltration: outbound HTTP POST to an unrelated domain, every 60 seconds
- Shell execution: spawns
osascripton macOS,powershell -w hiddenon Windows - Phantom dependency: a zero-download package appearing in a 100M-download package's tree
Any one of these might be innocent alone. Together, they're a textbook supply chain attack. The correlator recognizes the combination and forces the score to maximum. Verdict: BLOCK.
Here's what shows up on the PR:
Dependency Guardian — 2 packages scanned
| Package | Version | Score | Verdict |
|---------------|------------------|-------|---------|
| axios | 1.14.0 → 1.14.1 | 100 | BLOCK |
| other-package | 2.0.0 | 0 | pass |
[email protected] — BLOCKED (score 100)
CRITICAL install_script_exec: postinstall hook executes setup.js
HIGH obfuscated_code: reversed-Base64 + XOR cipher
HIGH network_exfiltration: HTTP POST to sfrclak[.]com every 60s
HIGH phantom_dependency: zero download history, new to tree
HIGH child_process: platform-specific shell execution
PR check: ✗ 1 blocked — ✓ 1 passed
The merge is blocked. The attack dies before npm install ever runs in production. Before the RAT writes to disk. Before anyone rotates certificates.
Why provenance, signing, and reputation all fail against compromised maintainer accounts
Four of the six largest supply chain attacks this past year came from compromised legitimate accounts. Provenance checks pass when the attacker has real credentials. Package signing passes when they have the real key. Reputation systems pass when the target package has millions of users.
Those tools answer "who published this?" That's worth knowing. But when a hijacked account publishes an XOR-encrypted payload that spawns hidden PowerShell, the question that matters is "what does this code do?"
CVE scanners catch known bugs. Behavioral scanners catch unknown malicious code. You need both. If you're choosing which to add next, and the threat you're worried about is the next Axios, behavioral scanning is the one that stops it.
Try it on your own dependencies
Install the GitHub App to scan PRs automatically when your lockfile changes. Your source code never leaves your machine.
Or run the CLI anywhere:
npm install -g @westbayberry/dg
Free tier: 1,000 scans/month, all 53 detectors. No credit card.
Benchmark results — 94.77% combined catch rate on a 17,874-package disclosed-malware corpus.
Related reading: - Behavioral npm Security Scanning: The Complete Guide - Dependency Guardian vs Socket.dev: An Honest Comparison
FAQ
What was the axios supply chain attack of March 2026?
In March 2026, an attacker social-engineered axios maintainer Jason Saayman, hijacked his session, and published two compromised versions (1.14.1 and 0.30.4) to npm. The compromised versions introduced a new dependency called plain-crypto-js containing a platform-specific remote access trojan (RAT). Axios has 100M weekly downloads; the attack reached OpenAI's macOS signing pipeline before it was caught.
Which axios versions were affected?
[email protected] and [email protected]. Both versions existed only on npm — neither had a corresponding GitHub release or CI artifact, which is a detectable signal on its own. The malicious versions were live for roughly three hours.
Why didn't npm audit, Snyk, or Dependabot catch the axios compromise?
All three tools work by checking packages against advisory databases. The malicious code was brand new — no CVE existed, no advisory had been filed, so none of them had anything to match against. Advisory-based scanners are retrospective by design: they tell you about attacks that have already been discovered and documented.
What is plain-crypto-js and why is it suspicious?
plain-crypto-js was the name chosen for the new dependency added to the compromised axios versions. The package had zero prior downloads, no GitHub presence, and a name designed to look like a crypto-js fork at a glance. It contained the RAT payload — macOS AppleScript execution, Windows PowerShell with hidden window, Linux Python reverse shell — that beaconed to a C2 server every 60 seconds.
How does behavioral scanning catch zero-day supply chain attacks like this?
Behavioral scanners read the actual source code instead of looking up known-bad hashes. On plain-crypto-js, Dependency Guardian's detectors fired on five independent signals — install script execution, obfuscated code (reversed Base64 + XOR), network exfiltration every 60s, platform-specific shell execution, and phantom-dependency status (zero-download package injected into a 100M-download tree). The correlator recognized the combination as an attack pattern and forced the score to 100 (block).
Is this different from the Shai-Hulud worm or the chalk/debug hijack?
The mechanism is the same — compromised maintainer credentials publishing malicious code — but the payload differs. Shai-Hulud was a self-propagating worm; chalk/debug was a short-lived crypto-stealer. All three share the property that every CVE scanner passed them clean during the window that mattered, and all three would have been caught by behavioral analysis on publish.