axios Got Hijacked and Your Machine May Be Compromised
A stolen npm token was all it took to poison axios, the package with 100 million weekly downloads, and drop a cross-platform RAT on every developer who ran npm install this morning.
Axios has roughly 100 million weekly downloads on npm and sits inside the dependency tree of most JavaScript projects built in the last decade. This morning, at 00:21 UTC on March 31st, 2026, an attacker used a stolen token to publish a trojanized version of it, and then did it again 39 minutes later against the legacy branch. The malicious packages were live for under three hours before npm yanked them. If you ran npm install in that window, your machine is compromised.
The attack had been staged the day before. On March 30th at 05:57 UTC, an attacker-controlled npm account called nrwise (email: nrwise@proton.me) published plain-crypto-js@4.2.0, a clean package, purely to establish a registry history. Let it sit a few hours, age a little, look legitimate. At 23:59 UTC that same day they swapped in plain-crypto-js@4.2.1, the weaponized version containing a postinstall hook that functions as a cross-platform RAT dropper. That was the payload, pre-staged and waiting.
Then the account takeover happened. The lead axios maintainer, jasonsaayman, had a long-lived classic npm access token stolen, the kind npm let developers generate for years before the push toward OIDC-based trusted publishing. The attacker changed the account's registered email to ifstap@proton.me and published both malicious versions manually from the CLI, with nothing in the GitHub history, no commit, no tag, no workflow trace for either version. A stolen token and two minutes of CLI work poisoned a package with 100 million weekly downloads.
The attacker added plain-crypto-js@^4.2.1 as a runtime dependency in the malicious axios versions. The package shows up in package.json but exists solely to trigger the postinstall hook; the axios codebase imports nothing from it. When npm resolves dependencies, it executes setup.js automatically. That script is obfuscated with a two-layer scheme, reversed base64 decoding then XOR cipher, and the first thing it does on execution is phone home to the C2 server at http://sfrclak.com:8000/6202033 (IP: 142.11.206.73) to pull a platform-specific second-stage payload.
On macOS the binary lands at /Library/Caches/com.apple.act.mond, named to blend into Apple system process listings, and runs via /bin/zsh. On Windows the dropper copies PowerShell to %PROGRAMDATA%\wt.exe, uses a hidden VBScript wrapper to execute a downloaded PS1 payload, and drops working files into %TEMP%. On Linux it downloads a Python script to /tmp/ld.py and launches it with nohup in the background. All three variants report back to the same C2 infrastructure. After launching the second stage, the dropper deletes itself: setup.js goes, the malicious package.json gets swapped out for a clean stub pre-staged in package.md. Post-infection, inspecting node_modules/plain-crypto-js shows nothing obviously wrong. The evidence is gone before you think to look for it.
Once the second-stage payload executes, the attacker has persistent, interactive access to the compromised machine. npm tokens, AWS access credentials, SSH private keys, CI/CD pipeline secrets, and the full contents of environment variables are all exposed. On a developer workstation or a CI/CD runner, that combination hands the attacker your entire infrastructure: cloud credentials, deployment keys, and every downstream system that trusts the environment those secrets live in.
npm unpublished both axios versions at around 03:15 UTC, placed a security hold on plain-crypto-js at 03:25 UTC, and by 04:26 UTC the malicious package had been replaced with a clean stub. The whole operation, from the attacker's first staged package to npm pulling the malicious versions, took under 24 hours.
This is the fourth npm supply chain attack since September 2025. On September 8th, 2025, a phishing attack compromised the npm account of "Qix", a maintainer whose packages include debug, chalk, ansi-styles, and supports-color. Eighteen packages were injected with a browser-resident crypto wallet interceptor covering over two billion combined weekly downloads, with the payload targeting browser contexts and end users with connected crypto wallets rather than the developers running npm install. The malicious versions lived roughly two hours before detection, almost exactly the same window as today's axios incident. Then a week later, on September 14th through 23rd, 2025, came Shai-Hulud: the first self-replicating worm ever documented in the npm ecosystem. It started with a compromised package called rxnt-authentication and spread rapidly to high-profile victims like @ctrl/tinycolor, reaching over 500 packages autonomously by scanning for GitHub personal access tokens and cloud credentials stored in victim environments, then using those stolen tokens to publish malicious versions of additional packages. CISA issued a formal alert. By November 2025, the Shai-Hulud variant had evolved to hit 796 packages covering more than 20 million weekly downloads and added a destructive payload triggered on a dead man's switch. February 2026 brought SANDWORM_MODE, 19 typosquatting packages aimed at AI development tools that combined credential harvesting with self-propagation. And now today.
The pattern across all of these is the same: obtain npm maintainer credentials through phishing or token theft, add a postinstall hook that runs arbitrary code on install, use that foothold to exfiltrate credentials and spread further. npm's architecture makes this straightforward because postinstall hooks run with the same permissions as the installing user, with no sandboxing and no approval step. From what I found in the StepSecurity analysis, the company has revoked many classic tokens and pushed maintainers toward OIDC-based publishing, but the installed base of legacy tokens from years of normal developer practice is enormous and the enforcement is voluntary.
Mitigation splits by exposure. If you ran npm install any time between 00:21 UTC and 03:25 UTC on March 31st, 2026, and your install resolved to axios 1.14.1 or 0.30.4, treat the machine as compromised and rotate every credential on that system: npm tokens, AWS IAM credentials, SSH keys, GitHub tokens, CI/CD secrets, and anything else stored as an environment variable. Rebuild from a known clean state. Checking for leftover artifacts (/Library/Caches/com.apple.act.mond on macOS, %PROGRAMDATA%\wt.exe on Windows, /tmp/ld.py on Linux) is worth doing, but the dropper self-deletes, so a clean filesystem check guarantees nothing.
If you installed axios outside that window or from a pinned version, verify your install with:
npm list axios 2>/dev/null | grep -E "1\.14\.1|0\.30\.4"
ls node_modules/plain-crypto-js 2>/dev/null && echo "CHECK THIS"
The safe versions are axios@1.14.0 on the 1.x branch and axios@0.30.3 on the legacy 0.x branch. Add an overrides block to your package.json to prevent any transitive dependency from pulling in a higher version until you've verified safety:
"overrides": {
"axios": "1.14.0"
}
For CI/CD pipelines, switch to npm ci --ignore-scripts. This flag prevents postinstall hooks from executing during automated installs. Some packages legitimately need postinstall scripts, native binaries and font tools being the common ones, but for most pure-JavaScript packages the hook is a foothold, and disabling it in CI is easy to deploy today. npm now publishes provenance attestations for packages released through GitHub Actions. Any version claiming to come from an automated workflow but carrying no attestation is worth a hard look before you run it.
The longer-term problem is that JavaScript's package ecosystem was built on trust and convenience at a time when supply-chain attacks against open-source maintainers were theoretical. Postinstall hooks are useful, long-lived tokens are convenient, and the maintainers behind 100 million weekly downloads are individual developers with personal email accounts and no institutional security backing. That combination is a reliable attack surface, and this wave has now demonstrated it four times. My guess is this specific incident gets cleaned up within a few days. The conditions that produced it will still be there next month.