JavaScript Library in 80% of Cloud Environments Got Poisoned
#EP35: Axios was clean. The hack hid in a dependency. Check your packages now.
If someone forwarded this to you — this is CoreCraft, where we write about the tech stories your team will be debating before the standup ends. Read this issue at corecraft.substack.com and subscribe if it’s useful.
At 05:57 UTC on March 30th, someone published a perfectly unremarkable npm package called plain-crypto-js. Version 4.2.0. Clean code, no payload. Just a new package sitting quietly on the registry, accumulating the kind of publishing history that automated scanners are trained to trust.
Eighteen hours later, they shipped 4.2.1.
That one wasn’t clean.
By midnight UTC on March 31st, two new versions of Axios had appeared on npm — 1.14.1 and 0.30.4. Both published using the stolen credentials of @jasonsaayman, the library’s lead maintainer. Neither touched a single line of Axios’s own source code. The only change: a new dependency, plain-crypto-js@4.2.1. A package Axios had never used. A package whose entire purpose was to execute one thing when npm processed it — a postinstall script that dropped a Remote Access Trojan onto whatever machine had just run npm install.
Payloads for macOS. For Windows. For Linux. Pre-built. Waiting.
Huntress picked up the first infections 89 seconds after the packages went live.
Why Axios, and Why It Worked
Axios is the HTTP client that JavaScript reaches for by default. More than 100 million downloads per week. Wiz puts it inside roughly 80% of cloud environments — React front-ends, CI/CD pipelines, serverless functions. If your team ships JavaScript, Axios is almost certainly somewhere in the tree.
The attack worked because the attacker didn’t try to be clever about the code. They were clever about the registry.
The attacker took over @jasonsaayman‘s npm account, changed its registered email to an anonymous ProtonMail address, and published the poisoned versions directly from the command line — bypassing the project’s GitHub Actions CI/CD pipeline entirely.
No source files modified.
No suspicious commits.
No PR.
Just a new dependency that npm install would automatically execute.
The dropper contacts a live command-and-control server and delivers platform-specific second-stage payloads. After execution, the malware deletes itself and replaces its own package.json with a clean version to avoid detection during post-infection inspection.
The staging beforehand is what makes this feel different from a smash-and-grab. The clean version of plain-crypto-js published 18 hours early was a deliberate step — build a registry footprint, avoid new-package alerts, look like a dependency that belongs. Both Axios release branches were hit within 39 minutes of each other. Three separate OS payloads pre-built. Every forensic trace designed to self-destruct on execution.
As StepSecurity’s CTO Ashish Kurmi put it: “This was not opportunistic.”
The Real Hole: A Legacy Token That npm Preferred Over OIDC
Here’s what’s genuinely unsettling about this, and it doesn’t get enough attention in the write-ups.
Axios had good security infrastructure. It published through GitHub Actions with OIDC Trusted Publisher — the system that cryptographically ties every release back to a verified CI/CD run. It carried SLSA provenance attestations. By every checklist, it looked solid.
But the project still passed a classic NPM_TOKEN as an environment variable alongside the OIDC credentials. When both are present, npm defaults to the token. The long-lived classic token was the real authentication method for every publish, regardless of how OIDC was configured.
The attacker never had to defeat OIDC. They used the door that was still open.
The new lock was installed. The old key was never taken off the hook.
Merritt Baer, CSO at Enkrypt AI and former Deputy CISO at AWS, said in an interview: “From my experience at AWS, it’s very common for old auth mechanisms to linger.” That’s the boring, honest answer. Not a zero-day. Not a novel bypass. Just an old token sitting alongside a newer system, and npm quietly preferring it.
What the RAT Actually Did
Once a compromised machine ran npm install, the dropper — an obfuscated Node.js script called setup.js — branched into one of three attack paths:
On macOS, an AppleScript payload fetched a compiled C++ binary from sfrclak.com:8000, saved it as /Library/Caches/com.apple.act.mond, made it executable, and launched it in the background. The AppleScript deleted itself afterward.
On Windows, the dropper located PowerShell, disguised a copy of it as wt.exe (Windows Terminal — subtle), wrote a VBScript to the temp directory, executed it, and fetched a PowerShell RAT. Unlike the other variants, this one added a Registry Run key so it survived reboots.
On Linux, a Python RAT was fetched and launched via nohup — no persistence across reboots, which points toward fast data exfiltration rather than long-term access.
On every compromised machine, the RAT immediately performed system reconnaissance: enumerating user directories, filesystem drive roots, and running processes, then transmitted this data to the C2. It maintained a 60-second beacon loop, ready to accept further commands including arbitrary script execution and in-memory binary injection.
The three payloads share an identical C2 protocol, command set, and message format — which suggests a single developer or tightly coordinated team working from a shared design.
Who Did It
Google’s Threat Intelligence Group formally attributed the attack to UNC1069, a suspected North Korean threat cluster with a history of supply chain operations targeting cryptocurrency and decentralized finance companies.
John Hultquist, GTIG’s chief analyst, said: “The full breadth of this incident is still unclear, but given the popularity of the compromised package, we expect it will have far reaching impacts.” Mandiant’s current estimate puts potential downstream victims at up to 10,000.
This is the third major npm supply chain compromise in seven months. Every one exploited maintainer credentials.
That pattern — not a novel technical vulnerability, but a stolen credential used to walk through the front door — is the thing worth sitting with.
If You Ran npm install Last Tuesday, Here’s What to Do
Safe versions: 1.14.0 (1.x branch) and 0.30.3 (0.x branch).
Check first:
Run
npm ls axiosin your project. Look for1.14.1or0.30.4.Check for RAT artifacts:
/Library/Caches/com.apple.act.mond(macOS),%PROGRAMDATA%\wt.exe(Windows),/tmp/ld.py(Linux).Audit CI/CD logs for any pipeline runs that installed during March 31, 00:21–03:00 UTC.
If you’re not affected:
npm install axios@1.14.0 --ignore-scripts
rm -rf node_modules/plain-crypto-jsAdd a version override to package.json to lock it down.
If you find IOCs: Don’t try to clean in place. Isolate the machine, re-image from a verified backup taken before March 30th, and rotate everything — tokens, keys, cloud credentials, secrets. Treat everything that machine touched as exposed.
Block egress to sfrclak[.]com at your firewall.
The Bigger Thing Here
The attack surface for your software isn’t really your software. It’s the humans who maintain the libraries yours depends on. One phished maintainer account. One forgotten npm token. That’s the delta between a clean pipeline and a RAT running reconnaisance on your production secrets at 1am.
ReversingLabs put it plainly: “The Axios attack should be understood as a template, not a one-time event.”
Three concrete things worth doing this week, none of them dramatic:
Audit your long-lived npm tokens. Find them across CI, .env files, GitHub secrets. Rotate them. Where possible, replace with OIDC — and confirm the OIDC is actually what npm uses, not a parallel token sitting alongside it.
Enable provenance checks. Legitimate Axios 1.x releases have OIDC provenance and SLSA attestations. The malicious versions had neither. A tool enforcing provenance checks would have flagged this gap immediately — but provenance verification is still opt-in.
Check postinstall scripts. npm install --ignore-scripts is blunt but fast. For critical packages in CI, know which ones run postinstall and why.
The boring hygiene stuff. Not exciting. But this entire attack hinged on a token that nobody got around to rotating.
Read every issue at corecraft.substack.com →
P.S. — Quick clarification before your Slack does it for you: Axios the JavaScript library and Axios the news site are completely unrelated. The news site is fine. The npm package had a rough Tuesday. We just wanted to name that before the “did you see Axios got hacked” message lands in your group chat.
P.P.S. — If this was useful, send it to whoever owns your team’s dependency security. Not as a “we have a problem” message. More of a “hey, have we audited our npm tokens lately?” nudge. That’s the only ask.
Help Us Shape Core Craft Better
TL; DR: Got 2 minutes? Take this quick survey to tell us who you are, what you care about, and how we can make Core Craft even better for you.
Thank You for Reading!
Loved this? Hit ❤️ to share the love and help others find it!
Get weekly tech insights to code smarter and build your dev career. Subscribe to Core Craft for practical tips and frameworks you can use today.
Have ideas or questions? Drop a comment—I reply to all! For collabs or newsletter sponsorships, email me at souravb.1998@gmail.com


