If you use JavaScript — and you probably do — there's a real chance your machine was briefly talking to a North Korean command-and-control server last week.
On March 31, 2026, two malicious versions of Axios were published to npm. Axios is the HTTP client library behind a huge portion of the JavaScript ecosystem, with over 100 million weekly downloads. The attack didn't touch Axios's source code. It didn't compromise GitHub. It exploited something much simpler: a stolen maintainer credential.
What actually happened
The attacker took over the npm account of jasonsaayman, the primary Axios maintainer. Once inside, they changed the account's email to an anonymous ProtonMail address and published two poisoned releases — axios@1.14.1 and axios@0.30.4 — directly via the npm CLI, completely bypassing the project's GitHub Actions CI/CD pipeline.
The malicious versions didn't modify any Axios code. Instead, they injected a single new dependency: plain-crypto-js@4.2.1. That package doesn't get imported anywhere in the codebase. Its only job is to run a postinstall script that drops a cross-platform Remote Access Trojan (RAT) targeting macOS, Windows, and Linux — then deletes itself and replaces its own package.json with a clean version to cover its tracks.
The staging was precise. Eighteen hours before the Axios releases, the attacker published a clean version of plain-crypto-js to build a publishing history and avoid new-package scanner alerts. Both release branches were hit within 39 minutes of each other.
The malicious versions were live for roughly three hours — from approximately 00:21 to 03:15 UTC. Huntress detected the first infections 89 seconds after the package went live.
Who was behind it
Microsoft Threat Intelligence and Google's Threat Intelligence Group both attributed the attack to a North Korean state-sponsored actor (referred to as Sapphire Sleet by Microsoft and UNC1069 by Google). The infrastructure matched backdoor tooling linked to prior operations targeting developers and financial organizations.
Are you affected?
Check your lockfiles and CI/CD logs for any of the following:
- axios@1.14.1
- axios@0.30.4
- plain-crypto-js (any version)
If you find them — especially if you ran npm install between 00:21 and 03:15 UTC on March 31 — assume compromise. Rotate all secrets: npm tokens, cloud keys, SSH keys, CI/CD secrets. Treat the host as fully compromised.
What to do right now
Immediate:
- Downgrade to axios@1.14.0 or axios@0.30.3
- Remove node_modules/plain-crypto-js and reinstall with npm install --ignore-scripts
- Rotate all credentials on affected systems
Going forward:
- Pin exact versions in package.json — avoid ^ or ~ ranges
- Use npm ci instead of npm install in CI/CD pipelines
- Disable automated dependency bots for Axios or configure them to hold until you've manually reviewed
- Require --ignore-scripts as a standard CI flag to block postinstall execution
- Verify that critical packages carry OIDC provenance metadata — the malicious Axios versions had none
The bigger picture
This isn't a one-off. This is the third major npm supply chain attack in seven months. Every single one started with a stolen maintainer credential. The attack surface isn't the registry — it's the humans with publishing access.
The lesson isn't to stop using open-source packages. It's to treat dependency updates with the same scrutiny you'd give a code review. Floating version ranges in production are a liability. npm ci in pipelines is non-negotiable. And provenance verification, while still opt-in, is increasingly a baseline expectation.
The supply chain is only as strong as its weakest key rotation policy.
