TL:DR: Malicious versions of Axios (1.14.1 and 0.30.4) hit the npm registry yesterday. They carry a malware dropper called plain-crypto-js@4.2.1. If you ran npm install in the last 24 hours, check your lockfile. Roll back to 1.14.0 and rotate every credential that was in your environment. Axios npm package is a fundamental building block of modern web development which has been compromised. Axios gets downloaded 83 million times a week. It’s used in almost everything. That’s exactly why someone targeted it. Axios Logo On March 30, attackers pushed two poisoned versions directly to npm – not a lookalike package, not a typo, the actual official package. They didn’t touch Axios’s core code, which would have triggered size-comparison alarms. Instead they introduced a malicious transitive dependency: plain-crypto-js@4.2.1. Most developers occasionally audit their direct dependencies. Almost nobody audits the dependencies of those dependencies. That’s the gap. The timeline is the part that should unsettle you. plain-crypto-js was published at 23:59:12 UTC on March 30, a brand new package with no prior history, created for this. The poisoned Axios versions went up roughly two minutes later. Socket’s detection flagged the anomaly at 00:05:41. Five minutes from dropper to infected package. This wasn’t manual; it was a script waiting to fire. How the Axios Supply Chain Attack Works The payload plain-crypto-js runs via a postinstall hook, so it executes the moment you run npm install. It decodes its C2 addresses at runtime to dodge static analysis, pulls in Node.js modules to run shell commands at your privilege level – run sudo npm install, the malware had root and knows what OS it’s on. Windows: it stages payloads in ProgramData. Linux/macOS: it hides in temp directories and tries to modify your shell profile so it survives a reboot. Then it deletes its own files, leaving responders with an empty directory and not much to work with. It calls home to sfrclak.com (142.11.206.73:8000) and exfiltrates environment variables. That’s your AWS keys. Your database passwords. Your API tokens. Whatever you had in .env. Inside the malicious plain-crypto-js Package The malware lives in setup.js (4,209 bytes) and runs automatically via npm’s postinstall lifecycle hook. When you run npm install, the script fires before you see a prompt. The execution path: npm install → postinstall hook → node setup.js → _entry(“6202033”) → OS detection → platform-specific payload → evidence deletion. After delivering its payload, the script deletes itself, renames package.md, and strips the postinstall hook from package.json so a post-infection scan sees nothing. Obfuscation: XOR + reversed Base64 All 18 attack strings – module names, the command-and-control URL, shell commands, file paths are hidden behind a two-layer encoding scheme. First, the string is reversed, underscores swapped for = padding characters, then base64-decoded. Then each character gets XORed against a key (OrDeR_7077) using an index formula of 7 × i² mod 10, with a constant of 333 applied to the XOR. This isn’t minification. Someone built this. Static decoding of all 18 entries reveals: Node.js modules (child_process, os, fs), the C2 URL ( http://sfrclak.com:8000/ ), platform-specific droppers for Windows, macOS, and Linux, and file targets for cleanup. Each platform sends a POST to a different path on a fake domain – packages.npm.org/product0 (macOS), /product1 (Windows), /product2 (Linux). The actual npm registry is registry.npmjs.org. Using a close lookalike is deliberate: it makes the malicious traffic blend into SIEM logs as routine registry traffic. Platform payloads MacOS – The dropper uses AppleScript to download a binary to /Library/Caches/com.apple.act.mond, mimicking Apple’s com.apple.* daemon naming. The binary is made executable and launched in the background via nohup. Windows – PowerShell gets located via where powershell and copied to %PROGRAMDATA%\wt.exe, disguised as “Windows Terminal” to sidestep EDR rules that watch powershell.exe. A VBScript wrapper then downloads a .ps1 script to %TEMP%\6202033.ps1 and runs it with -w hidden -ep bypass. Linux – curl downloads a Python script to /tmp/ld.py and runs it detached with nohup python3. The macOS second-stage RAT Elastic Security’s Joe Desimone reverse-engineered the macOS binary. It’s a C++ remote access trojan with the following capabilities: Beaconing – Every 60 seconds it phones home with hostname, username, macOS version, timezone, CPU type, and directory listings of /Applications and ~/Library. User-Agent masquerade – It presents as Internet Explorer 8 on Windows XP. Probably to blend in as “weird but old” traffic rather than obviously attacker-tooling. peinject – Receives a Base64-encoded binary, writes it to a hidden temp file, codesigns it ad hoc, and runs it. runscript – Executes shell commands or AppleScripts on demand. rundir – Enumerates filesystems for exfiltration. Why GitHub showed nothing v1.14....
The Axios npm package was compromised via a supply chain attack where malicious versions 1.14.1 and 0.30.4 introduced a transitive dependency (`plain-crypto-js@4.2.1`) that executes a malware dropper via a postinstall hook to exfiltrate environment variables. Users must immediately roll back to version 1.14.0, audit their lockfiles for the malicious dependency, and rotate all credentials present in the affected environment.