Axios Supply Chain Attack — North Korea Owned npm Installs
UNC1069 hijacked axios@1.14.1 and axios@0.30.4, shipping a cross-platform RAT to 100M weekly downloads. Here is exactly what happened and what to do now.
On March 31, 2026 at 00
UTC, a North Korea-linked threat actor designated UNC1069 by Google’s Threat Intelligence Group hijacked the npm account of axios lead maintainer Jason Saayman and published two backdoored versions —axios@1.14.1 and axios@0.30.4 — into a package with 100 million weekly downloads. By approximately 03 UTC, clean versions were restored. In those three hours, every npm install that resolved latest or legacy pulled a cross-platform Remote Access Trojan onto the developer’s machine or CI/CD runner — silently, automatically, without a single prompt.
TL;DR
- Exposure window: 2026-03-31 00 UTC to ~03 UTC. Any
npm installin this window may have pulled malicious axios. - Compromised versions:
axios@1.14.1(taggedlatest) andaxios@0.30.4(taggedlegacy). Safe pins:1.14.0and0.30.3. - Mechanism: Hidden dependency
plain-crypto-js@4.2.1executednode setup.jsvia postinstall hook — no user interaction required. - Claude Code users: If you installed or updated Claude Code via npm during the window, treat the machine as compromised. Rotate all credentials.
- Attribution: UNC1069, North Korea-nexus APT — a separate campaign from the concurrent TeamPCP attacks on Trivy, LiteLLM, and Telnyx.
What Happened
The attack chain was precise. UNC1069 obtained a stolen long-lived npm access token for the axios package — bypassing the OIDC/GitHub Actions CI/CD pipeline that legitimate axios releases use — and changed the maintainer email to an attacker-controlled address (ifstap@proton.me), locking out the real maintainer. They then published axios@1.14.1 tagged as latest and axios@0.30.4 tagged as legacy. Both versions introduced a hidden dependency: plain-crypto-js@4.2.1.
The plain-crypto-js package was not yet uploaded when the malicious axios versions were published — a deliberate detection evasion technique. When npm resolved the dependency tree and the package appeared, it executed an obfuscated dropper named setup.js via a postinstall hook. npm runs postinstall scripts by default. The script ran without any prompt, any warning, or any user interaction.
The payload was platform-specific: PowerShell-based on Windows, a C++ Mach-O binary on macOS, and a Python backdoor on Linux. All three shared the same C2 protocol — Google’s Threat Intelligence Group named it WAVESHAPER.V2. It is a full Remote Access Trojan: persistent, cross-platform, and capable of credential exfiltration.
StepSecurity’s behavioral monitoring flagged the anomaly. Clean versions were restored at approximately 03
UTC. The malicious versions were live for under three hours.// What your package-lock.json looked like if you were hit
{
"node_modules/axios": {
"version": "1.14.1",
"dependencies": {
"plain-crypto-js": "4.2.1"
}
}
}
If you see 1.14.1, 0.30.4, or plain-crypto-js anywhere in your lockfile, stop reading this article and start your incident response.
Triage checklist — do this now if you ran npm install on March 31:
- Search
package-lock.json,yarn.lock, orbun.lockbfor1.14.1,0.30.4, orplain-crypto-js.- If found: treat the machine as fully compromised. Do not patch — rebuild from a clean OS image.
- Rotate everything that was present at install time: npm tokens, GitHub PATs, SSH keys, AWS/GCP/Azure API keys, CI/CD secrets, any
.envvalues.- Safe versions to pin to:
axios@1.14.0(1.x branch) andaxios@0.30.3(0.x branch).
Why This Matters
This is not a novel attack class. npm postinstall script abuse has been documented since at least 2018. The structural conditions that made this possible — unpinned dependencies, default postinstall execution, long-lived access tokens with no expiry, no provenance requirement in lockfiles — have been discussed in security circles for years. The fix has been available the entire time. The industry just didn’t care enough to ship it until the blast radius became impossible to dismiss.
The axios attack is distinguished from typical supply chain incidents by three things: scale, context, and sophistication.
Scale. A hundred million weekly downloads is not a niche package. Axios is in the dependency tree of a substantial fraction of every Node.js application, CI/CD pipeline, and developer tooling suite in production. The attacker did not target a specific organization — they targeted the JavaScript ecosystem’s trust infrastructure directly.
Context. This is the second independent nation-state supply chain campaign targeting the JavaScript and Python developer toolchain in twelve days. The TeamPCP campaign, attributed to a separate threat actor, compromised Trivy, LiteLLM, and Telnyx between March 19 and 27. Two independent APT-level operations, same twelve-day window, same target surface: the tools developers use to build things. If you are still treating supply chain security as an edge case, these two weeks are your corrective.
Sophistication. The attacker changed the maintainer email to lock out the real maintainer before publishing — a credential lockout maneuver. They used a delayed dependency upload as a detection evasion technique. They delivered platform-specific payloads with a shared C2 protocol across all three major operating systems. This is not opportunistic. This is a campaign with preparation.
The Claude Code-specific exposure is worth naming directly. Users who installed or updated Claude Code via npm during the 00
to 03 UTC window may have pulled the trojanized axios. This is not a theoretical attack path — it is the exact population of machines that were at risk. Anthropic has now designated the native installer (curl -fsSL https://claude.ai/install.sh | bash) as the only recommended installation path, because it uses a standalone binary that bypasses the npm dependency chain entirely.
What SLSA provenance would have done here. The shift from OIDC/SLSA provenance publishing — used on all legitimate axios releases — to a direct CLI publish with a changed maintainer email was detectable. StepSecurity’s behavioral monitoring flagged it within minutes. Projects that require SLSA provenance verification in their lockfiles would have rejected the malicious versions automatically. Most projects do not require this. The tooling to enforce it exists today: npm’s
--provenanceflag for publishing, and provenance verification in install tooling. The gap is not technical; it is adoption.
The comparison point that matters here is the LiteLLM supply chain attack from the same twelve-day window. In that incident, the attack vector was also a dependency with a postinstall hook, also targeting an AI developer tooling package, also attributed to an APT. The difference is blast radius. LiteLLM is a significant package. Axios is load-bearing infrastructure for the JavaScript ecosystem. Scaling up from LiteLLM to axios is not a coincidence — it is a campaign that found a larger target.
The Take
I keep saying the developer toolchain is the new perimeter. March 31 is the clearest evidence yet that this is not a theoretical concern.
The fix that would have blocked this attack has been available for two years. Requiring SLSA provenance in lockfiles, blocking postinstall scripts in CI by default, and rotating to short-lived npm tokens instead of long-lived access tokens — none of these are hard. npm supports --ignore-scripts in CI environments today. You can add ignore-scripts=true to your .npmrc in about thirty seconds. Most teams have not done it because the cost of being wrong felt abstract, and the cost of being secure felt like friction.
The blast radius is no longer abstract. One three-hour window, one compromised maintainer account, one package with a hundred million weekly downloads, and WAVESHAPER.V2 is running on developer machines and CI runners worldwide.
The attack vector isn’t a zero-day in your application code. It’s the fact that npm install runs arbitrary scripts by default and almost nobody pins to provenance-verified lockfiles.
The structural changes are not complicated: lock your dependencies to provenance-verified lockfiles, add ignore-scripts=true to your CI .npmrc, and move to short-lived OIDC tokens for any package you publish. If you use Claude Code or any other AI coding tool distributed via npm, verify your installation path today and switch to the native installer if one exists.
What you should not do is treat this as an axios-specific problem that was fixed when the malicious versions were pulled. UNC1069 and TeamPCP are two separate APT-level campaigns that targeted developer tooling in the same twelve days. The target surface is every package manager that runs arbitrary code during installation, and the JavaScript ecosystem is not the only one.
The debate about whether AI coding tools have an acceptable security posture should be over. The tools themselves are now explicitly in the target profile of nation-state threat actors. That changes the calculus on every npm install you run in a privileged environment.