DEV Community

Cover image for axios npm Supply Chain Attack (March 31, 2026) — What Happened and How to Check Your Lock File Right Now
LazyDev_OH
LazyDev_OH

Posted on • Originally published at gocodelab.com

axios npm Supply Chain Attack (March 31, 2026) — What Happened and How to Check Your Lock File Right Now

On March 31, 2026, malicious versions of axios — a package with 70M+ weekly downloads — were published to npm after the maintainer's account was hijacked via social engineering. Versions 1.14.1 and 0.30.4 were pushed back-to-back, both carrying a plain-crypto-js@^4.2.1 dependency that deploys a cross-platform RAT through a postinstall hook.

The malicious releases sat on the registry for roughly 3 hours. In that window, an estimated 600,000 installs occurred.

If you use axios, check your lock file. Now.

TL;DR

  • Malicious: axios@1.14.1, axios@0.30.4
  • Safe: axios@1.14.0, axios@0.30.3 (pre-incident), 1.15.0+ / 0.30.5+ (post-incident)
  • Attribution: North Korea — Sapphire Sleet (Microsoft) / UNC1069 (Google)
  • Action: wipe node_modules, reinstall, rotate all credentials

axios supply chain attack timeline


How to Check Right Now

# Installed axios version
npm list axios

# Check lock file for malicious versions
grep -E "axios@(1\.14\.1|0\.30\.4)|plain-crypto-js" package-lock.json

# Monorepo-wide scan
find . -name "package-lock.json" -not -path "*/node_modules/*" \
  | xargs grep -l "plain-crypto-js\|1.14.1\|0.30.4"
Enter fullscreen mode Exit fullscreen mode

If grep returns a match, remediate immediately. No output means you're probably fine — but also check git history. If the malicious version was ever installed in the past, the postinstall hook has already run.

# Did the malicious version ever land in lock file history?
git log -p -- package-lock.json | grep -E "1\.14\.1|0\.30\.4|plain-crypto-js"
Enter fullscreen mode Exit fullscreen mode

With pnpm, use pnpm list axios; with yarn, yarn list --pattern axios. The lock-file grep pattern applies regardless of package manager.


The 3-Hour Timeline

Independent reconstructions from Aikido Security, Arctic Wolf, and Elastic Security Labs largely agree:

Time (UTC) Event
2026-03-31 00:21 axios@1.14.1 published — targets 1.x line, adds plain-crypto-js@^4.2.1
+39 min Attacker stages the 0.x legacy release
01:00 axios@0.30.4 published — 0.x branch compromised
~03:00 Socket.dev / Aikido detect anomalous postinstall hook, community alerts begin
~04:00 npm force-unpublishes both versions, exposure totals ~3 hours

"Only 3 hours" is a dangerous framing. Vercel, GitHub Actions, CircleCI, and similar CI environments pull fresh versions on cache misses every 10~30 seconds. Globally, tens of thousands of builds ran in that window. Several regions also reported CDN cache serving the malicious version briefly after the unpublish.


How the Malicious Code Works

plain-crypto-js disguises itself as a crypto utility. It is never imported anywhere in axios source — it exists solely to execute its postinstall hook.

During install, npm runs postinstall automatically. That hook contacts the attacker's C2 server and pulls a second-stage payload. The payload detects the host OS (macOS / Windows / Linux) and drops a matching RAT (Remote Access Trojan).

Per Elastic Security Labs, the C2 protocol rides on HTTPS with a custom command set designed to blend into normal API traffic, making network-level detection difficult.

axios attack impact stats


Attack Vector — Maintainer Account Hijack

Per SANS Institute and The Hacker News, the axios maintainer account was hijacked through a targeted social engineering campaign. The attacker changed the account email to ifstap@proton.me, then abused publish permissions to push the two malicious releases.

Attribution

  • Microsoft Threat Intelligence: Sapphire Sleet — North Korea state actor
  • Google GTIG: UNC1069 — same actor, tracked independently
  • Joint attribution confirmed

UNC1069 / Sapphire Sleet has a track record of targeting developers through:

  1. Fake job offers with malicious coding-test files
  2. Fake recruiter outreach via LinkedIn or Telegram
  3. Phishing open-source maintainers directly

This axios case appears to fall into the third pattern.


Remediation

Don't just upgrade — wipe and rebuild.

# 1. Wipe node_modules + lock file
rm -rf node_modules package-lock.json

# 2. Clean cache
npm cache clean --force

# 3. Reinstall latest safe version
npm install axios@latest

# 4. Verify
grep "plain-crypto-js" package-lock.json
# → No output = clean
Enter fullscreen mode Exit fullscreen mode

Apply the same to deployment environments (Vercel / Netlify / GitHub Actions caches). A stale cache can still serve the compromised artifact.


Rotate All Credentials — Not Just Env Vars

If a malicious version ever reached your machines, the RAT may still be resident. The attacker has system-level access, not just process.env.

Rotation checklist:

  • [ ] AWS / GCP / Azure access keys
  • [ ] AI API keys — OpenAI / Anthropic / Gemini
  • [ ] Database passwords — PostgreSQL, MySQL, MongoDB
  • [ ] Payment API keys — Stripe, LemonSqueezy, Paddle
  • [ ] GitHub Personal Access Token + SSH keys
  • [ ] App secrets — NEXTAUTH_SECRET, SESSION_SECRET
  • [ ] Webhook secrets for external services
  • [ ] Infected-machine SSH public keys — remove from ~/.ssh/authorized_keys on any servers they reached

Revoke old keys immediately after issuing new ones. Keeping the old key alive defeats the rotation.

For machines with high suspicion of compromise, an OS reinstall is the safest option. CI runner images should be rebuilt clean. Local dev machines should at minimum clear browser sessions, SSH keys, and saved AWS CLI profiles, then reconfigure.


Prevention Routines

1. Commit lock files. Without a lock file, every build can pull a different version. If package-lock.json is in .gitignore, remove it now.

2. Put npm audit in CI. Run it on every PR. npm audit --audit-level=high catches high-severity issues at minimum. Caveat: audit only sees what's public in the CVE database.

3. Tighten version range specifiers.

//  Too loose  opens the door to auto-updates
"axios": "^1.13.0"

//  Exact pin
"axios": "1.14.0"

//  Patch-only
"axios": "~1.14.0"
Enter fullscreen mode Exit fullscreen mode

4. Monitor beyond CVE.

Tool Strength Note
Dependabot Built into GitHub CVE-based, limited against fresh attacks
Socket.dev Behavioral analysis Flagged this axios incident early
Aikido Security Real-time behavioral Published first public analysis
Snyk Scan + remediation Free tier available
npm audit Built-in CVE-based limits

Realistic combo: Dependabot + Socket.dev. Single-tool reliance leaves blind spots.


Why This Keeps Happening

The npm ecosystem has a low publishing bar. A single account compromise can poison a package used by hundreds of millions of developers. That structural fact isn't changing fast.

  • XZ Utils (2024-03) — compromised Linux distribution backdoor
  • event-stream (2018) — crypto wallet stealer hidden in dependency
  • ua-parser-js (2021) — malicious versions with credential stealer
  • axios (2026-03) — this incident

axios isn't the first and won't be the last.

Following this incident, npm is reportedly considering mandatory 2FA expansion and a 24-hour cooldown on maintainer email changes. GitHub already required 2FA for top npm maintainers since 2024, but this hijack went through the email recovery flow. Security chains only hold as strong as the weakest link.


Key Takeaways

  1. Check your lock file right now — don't assume you're fine.
  2. Wipe, don't just upgrade — stale caches and remnant RATs are real risks.
  3. Rotate credentials broadly — system-level access means everything is suspect.
  4. Put behavioral analysis in your CI — CVE-based tools can't catch fresh attacks.
  5. Pin exact versions for critical packages — range specifiers are attack surface.

Trusting a popular package and verifying it are different things. If you use axios, put a version check in your routine starting today.


Sources:


Originally published on GoCodeLab — April 2026.

Top comments (0)