We Almost Got Hit by the Axios Supply Chain Attack. Here's What Saved Us.
- Patrick Duggan
- Mar 31
- 5 min read
Updated: Apr 25
Yesterday someone hijacked the most popular HTTP client in the JavaScript ecosystem and turned it into a cross-platform RAT. We run 18 services on axios. Every single one of them would have pulled the malicious version on a fresh install. A lock file is the only reason I'm writing this post instead of an incident report.
What Happened
On March 30, 2026, an attacker compromised the npm account of axios maintainer @jasonsaayman — likely by stealing a long-lived npm access token. They changed the account email to [email protected], then published two poisoned versions: [email protected] and [email protected]. Both the current 1.x branch and the legacy 0.x branch. Both within 39 minutes of each other.
The malicious versions inject a dependency called [email protected] — a package that had been pre-staged 18 hours earlier under a clean version (4.2.0) by a different attacker account ([email protected]). The clean version established publishing history. The weaponized version carried a postinstall script that acts as a RAT dropper targeting macOS, Windows, and Linux.
This was not opportunistic. Three OS-specific payloads, pre-built and staged. Two release branches hit in under an hour. Every trace designed to self-destruct.
How the RAT Works
The postinstall script in [email protected] fingerprints the OS and drops a platform-specific second-stage payload:
macOS: Native Mach-O binary, persists as /Library/Caches/com.apple.act.mond
Windows: PowerShell dropper, persists as %PROGRAMDATA%\wt.exe
Linux: Python script dropped to /tmp/ld.py
Once installed, the RAT beacons system information and file listings to the C2 server at sfrclak[.]com:8000 every 60 seconds. POST requests go to /6202033 with a body containing packages.npm.org/product0 (macOS), product1 (Windows), or product2 (Linux).
The behavioral tell: Node.js spawning curl, osascript, cscript, or python3 as child processes from a working directory inside node_modules/. If your EDR sees that, you have a problem.
Why We Didn't Get Hit
We have 18 services declaring axios as a dependency, all with caret ranges:
"axios": "^1.13.4"
"axios": "^1.12.2"
"axios": "^1.7.9"
"axios": "^1.6.0"Every single one of these resolves to 1.14.1 on a fresh npm install. That's how semver works — the caret says "give me anything compatible." The attacker knew this. That's why they chose version 1.14.1 and not 1.13.6. Maximum blast radius within the expected range.
What saved us: lock files. Our package-lock.json files pin to 1.13.5. As long as you install with the lock file present, npm respects the pinned version. No lock file, no protection.
As of this morning, we've removed every caret range and pinned all 18 services to exact 1.13.5. No more trusting semver with our supply chain.
The Timeline
Socket.dev's automated detection flagged plain-crypto-js within six minutes of publication. Six minutes. The malicious versions were live on npm for approximately 2-3 hours before npm pulled them.
Axios gets downloaded roughly 100 million times per week. In that 2-3 hour window, observed execution occurred in 3% of affected environments according to early reports. At axios's scale, 3% is a terrifying number.
Pattern 38
We've been documenting this class of attack since December 2025. We call it Pattern 38 — supply chain attacks that weaponize the trust developers place in package registries, GitHub repos, and community tooling.
In December, it was malware hidden in GitHub ZIP downloads. In January, a fake Cisco FMC "proof of concept" on GitHub that was actually a webshell. In February, fork farms pushing trojanized npm packages through auto-named GitHub accounts.
The axios attack is Pattern 38 at scale. Same playbook — compromise trust infrastructure, inject malicious dependency, ride the distribution network. The difference is the target: a package that sits in 80% of cloud environments. The attacker didn't need to trick anyone into installing anything new. They just had to poison something everyone already depends on.
The Bypass That Matters
Microsoft pulls this feed daily. AT&T pulls this feed daily. Starlink pulls this feed daily. Get the DugganUSA STIX feed — $9/mo →
Every legitimate axios release goes through GitHub Actions using npm's OIDC Trusted Publisher mechanism. This cryptographically ties each publish to a verified GitHub workflow. No GitHub commit, no publish.
The attacker bypassed this entirely. They published directly via the npm CLI with a stolen long-lived access token. No OIDC binding. No corresponding GitHub commit or tag. The CI/CD pipeline — the thing that's supposed to prevent exactly this — was irrelevant because the attacker had a credential that predated it.
Long-lived access tokens are the skeleton key of supply chain security. If your npm account has one, revoke it. Today.
IOCs
Type | Value | Description |
Domain | sfrclak[.]com | C2 server |
IP | 142.11.206.73 | C2 IP (sfrclak.com) |
URL | hxxp://sfrclak[.]com:8000/6202033 | C2 beacon endpoint |
SHA256 | 5bb67e88...71cd | [email protected] malicious package |
SHA256 | 59336a96...0c0f | [email protected] malicious package |
SHA256 | fcb81618...75cf | Linux RAT payload |
SHA256 | 92ff0877...45a | macOS RAT payload |
SHA256 | 617b67a8...d101 | Windows PowerShell payload |
Package | Malicious dependency (RAT dropper) | |
Persistence | /Library/Caches/com.apple.act.mond | macOS artifact |
Persistence | %PROGRAMDATA%\wt.exe | Windows artifact |
Persistence | /tmp/ld.py | Linux artifact |
Full SHA256 hashes: `` [email protected]: 5bb67e88846096f1f8d42a0f0350c9c46260591567612ff9af46f98d1b7571cd [email protected]: 59336a964f110c25c112bcc5adca7090296b54ab33fa95c0744b94f8a0d80c0f Linux payload: fcb81618bb15edfdedfb638b4c08a2af9cac9ecfa551af135a8402bf980375cf macOS payload: 92ff08773995ebc8d55ec4b8e1a225d0d1e51efa4ef88b8849d0071230c9645a Windows payload: 617b67a8e1210e4fc87c92d1d1da45a2f311c08d26e89b12307cf583c900d101 ``
These IOCs are now indexed in our STIX feed. If you're a consumer, they're already in your next pull.
What To Do Right Now
Check your axios version: npm ls axios in every project. If you see 1.14.1 or 0.30.4, assume compromise.
Search for artifacts: Check for /Library/Caches/com.apple.act.mond (macOS), %PROGRAMDATA%\wt.exe (Windows), /tmp/ld.py (Linux).
Search network logs: Any outbound to sfrclak.com or 142.11.206.73 means the RAT executed.
Pin your versions: Remove caret ranges. Use exact versions in package.json. Trust the lock file, but don't rely on it alone.
Revoke long-lived npm tokens: If you maintain packages, switch to OIDC Trusted Publishers. Kill every long-lived token.
Monitor node child processes: Node spawning curl, osascript, cscript, or python3 from node_modules/ is never normal.
The Boring Work
A lock file saved us. Not a fancy tool. Not an AI-powered scanner. A lock file.
The boring operational discipline — pinning versions, maintaining lock files, not running npm install without one — is what stands between your codebase and a RAT that beacons every 60 seconds. We've been saying this since Pattern 38 dropped in December: supply chain security isn't a product you buy. It's the boring work you do every day.
We indexed these IOCs into our STIX feed within hours of the attack. They're available now at analytics.dugganusa.com/api/v1/stix-feed. If you're running a SIEM, point it there. If you're not, maybe today's the day.
Sources: StepSecurity (first detection), Socket.dev (6-minute flag), Snyk, Aikido, Wiz, Semgrep, SOCRadar, Huntress, OSSF malicious-packages (MAL-2026-2307)
DugganUSA tracks supply chain attacks as Pattern 38. This is the 14th documented instance since December 2025.
The cheapest, fastest, most accurate threat feed on the internet.
275+ enterprises pulling daily. 1M+ IOCs. 17.4M indexed documents. We beat Zscaler by 43 days on NrodeCodeRAT. Starter tier $9/mo — less than any competitor’s sales demo.




Comments