atareh

Research & Op-ed · MAR 31, 2026

Axios got hacked: how to check if you're compromised and lock down npm

On March 30, 2026, two malicious versions of axios were published to npm, dropping a RAT on macOS, Windows, and Linux. Here's how to check your system, what to do if you're affected, and how to prevent it from happening again.

atareh
@atareh
MAR 31, 2026 · 5 min read
SecuritynpmSupply Chain

What happened

On March 30, 2026, a compromised maintainer account was used to publish two malicious versions of axios to npm: 1.14.1 and 0.30.4. Axios is the most popular HTTP client library in the JavaScript ecosystem with over 300 million weekly downloads.

The malicious versions injected a hidden dependency called plain-crypto-js@4.2.1, which runs a postinstall script that drops a cross-platform Remote Access Trojan (RAT) on macOS, Windows, and Linux. The RAT establishes persistence and phones home to a command-and-control server.

Both versions have since been unpublished from npm, but anyone who ran npm install or bun install during the window could have pulled them in — especially if their dependencies use unpinned version ranges like ^1.13.0.


Who is affected

You're at risk if any of the following are true:

  • You ran npm install, bun install, yarn install, or pnpm install on March 30, 2026
  • You deleted your lockfile and reinstalled dependencies recently
  • You have axios as a direct dependency with a caret range (^1.x)
  • You installed a package that depends on axios transitively

Even if you don't use axios directly, many popular packages depend on it. This is what makes supply chain attacks so dangerous — the blast radius extends far beyond direct users.


Check your system

If you use Claude Code, paste the block below into your terminal. It will check everything — installed versions, lockfiles, node_modules, RAT artifacts, and unpinned dependencies across all your projects.

shell
Check my system for the axios supply chain attack from March 30, 2026.

Two malicious versions were published: axios@1.14.1 and axios@0.30.4.
They inject a hidden dependency called plain-crypto-js that drops a
cross-platform RAT via a postinstall script.

Run ALL of these checks and report what you find:

1. CHECK INSTALLED VERSIONS
   - Run: npm list axios 2>/dev/null (check for 1.14.1 or 0.30.4)
   - Run: npm list -g axios 2>/dev/null (check global installs)
   - Search all node_modules for axios: find ~/  -maxdepth 6 \
     -path "*/node_modules/axios/package.json" 2>/dev/null and
     check each version

2. CHECK LOCKFILES
   - Find all package-lock.json files: find ~/ -maxdepth 5 \
     -name "package-lock.json" -not -path "*/node_modules/*"
   - Grep each for "1.14.1" or "0.30.4"
   - Also check yarn.lock and bun.lockb if they exist

3. CHECK FOR THE MALICIOUS DEPENDENCY
   - Search for plain-crypto-js: find ~/ -maxdepth 5 \
     -name "plain-crypto-js" -type d 2>/dev/null
   - Also check: ls node_modules/plain-crypto-js in each project

4. CHECK FOR RAT ARTIFACTS
   - macOS: ls -la /Library/Caches/com.apple.act.mond
   - Linux: ls -la /tmp/ld.py
   - Windows: check %APPDATA%\Microsoft\Windows\Start Menu\
     Programs\Startup for suspicious files
   If ANY of these exist, the system is COMPROMISED.

5. CHECK FOR UNPINNED DEPENDENCIES (future risk)
   - Find all package.json files and check if axios uses
     caret (^) or tilde (~) ranges
   - These would auto-resolve to a malicious version if one
     were published again
   - Flag any that say "^1.x", "~1.x", or wide ranges like "1.x"

Report: for each check, tell me if I'm clean or affected.
If anything is compromised, tell me EXACTLY what to do.

If you don't use Claude Code, here are the raw commands to run yourself:

Check for malicious versions

shell
# Check all installed axios versions
npm list axios 2>/dev/null | grep -E "1\.14\.1|0\.30\.4"
npm list -g axios 2>/dev/null | grep -E "1\.14\.1|0\.30\.4"

# Check lockfiles
grep -r "1.14.1\|0.30.4" package-lock.json 2>/dev/null

# Check for the malicious dependency
find ~/ -maxdepth 5 -name "plain-crypto-js" -type d 2>/dev/null

Check for RAT artifacts

shell
# macOS
ls -la /Library/Caches/com.apple.act.mond 2>/dev/null && \
  echo "COMPROMISED" || echo "Clean"

# Linux
ls -la /tmp/ld.py 2>/dev/null && \
  echo "COMPROMISED" || echo "Clean"

Check for unpinned dependencies

shell
# Find all package.json files with unpinned axios
find ~/ -maxdepth 5 -name "package.json" \
  -not -path "*/node_modules/*" -exec \
  grep -l '"axios"' {} \; 2>/dev/null | while read f; do
    echo "--- $f ---"
    grep '"axios"' "$f"
done

What to do if compromised

Immediate actions:

  1. Disconnect from the network to stop any active exfiltration
  2. Rotate all credentials that were accessible from that machine: npm tokens, SSH keys, cloud provider credentials (AWS, GCP, Azure), GitHub tokens, database passwords, and anything in .env files
  3. Check your npm account for unauthorized publishes — the RAT may have used your npm token to publish malicious versions of your own packages
  4. Rebuild from a known-good state — don't trust the compromised OS
  5. Audit git history for any commits you didn't make

If you only found the malicious axios version but no RAT artifacts:

shell
# Pin to the latest clean version
npm install axios@1.14.0

# Remove the malicious dependency
rm -rf node_modules/plain-crypto-js

# Reinstall without running scripts
npm install --ignore-scripts

# Verify
npm list axios

Lock down your system

Whether or not you were affected, now is the time to harden your npm configuration. The attack worked because postinstall scripts run automatically by default and most dependencies use unpinned version ranges.

Create a global .npmrc

shell
cat > ~/.npmrc << 'EOF'
# Block postinstall scripts by default (the axios attack vector)
ignore-scripts=true

# Always respect lockfiles
package-lock=true

# Auto-audit on install
audit=true
audit-level=moderate
EOF

Pin your dependencies

Replace caret ranges with exact versions in your package.json:

shell
# Before (vulnerable to new malicious versions)
"axios": "^1.13.5"

# After (locked to a specific known-good version)
"axios": "1.13.5"

You can also use npm config set save-exact true to make npm always save exact versions when you install new packages.

Never delete your lockfile

Your package-lock.json pins every transitive dependency to an exact version. If you delete it and reinstall, npm resolves everything fresh — which is exactly how supply chain attacks spread. Commit your lockfile, and if it has merge conflicts, resolve them instead of deleting.


The bigger picture

Andrej Karpathy put it well: you can defend yourself locally with pinned versions and containers, but the defaults of package managers need to change. A single compromised account shouldn't be able to silently push malware to millions of developers through unpinned dependencies.

This isn't the first supply chain attack on npm (event-stream in 2018, ua-parser-js in 2021, colors and faker in 2022) and it won't be the last. The ecosystem incentivizes convenience over security — npm install runs arbitrary code on your machine by default, and most projects accept any semver-compatible version.

Until the ecosystem changes, the responsibility is on you. Lock your dependencies, disable scripts by default, and audit what you're installing. The five minutes of setup in this guide could save you from a full credential rotation and machine rebuild.

atareh

Written by

@atareh

AI architect & creator. Writing, designing, and producing in AI and tech. Previously head of product at a healthtech SaaS; background in molecular science. Founded gogray.today in 2017.

Related

Keep reading.

Made by @atareh · x / twitter · instagram