If you’re running a Node.js build pipeline, CI/CD system, or any service that runs npm install, you need to check your node_modules today. The axios HTTP client โ 100 million weekly downloads, present in roughly 80% of cloud environments โ was backdoored on March 31 and shipped a cross-platform remote access trojan to any system that ran a fresh install between approximately 00:21 and 03:20 UTC.
Timeline
The attack was a staged operation spanning roughly 24 hours:
- March 30, 05:57 UTC โ Attacker publishes a clean decoy package,
[email protected], establishing registry presence without triggering alerts - March 30, 23:59 UTC โ Malicious
[email protected]published with the full RAT dropper payload - March 31, 00:21 UTC โ
[email protected]published, injecting[email protected]as a runtime dependency (taggedlatest) - March 31, 01:00 UTC โ
[email protected]published with same backdoor (taggedlegacy, targeting older pinned versions) - March 31, ~03:20 UTC โ Malicious versions removed from npm registry
The two-version strategy was deliberate: hitting both the current 1.x branch and the older 0.x branch maximizes blast radius across projects that haven’t migrated to newer releases.
What’s Vulnerable
Any system that ran npm install or resolved axios as a dependency between 00:21โ03:20 UTC on March 31 and pulled [email protected] or [email protected]. The exposure window is narrow but axios’s install velocity (over 100M weekly) means tens of thousands of installs likely occurred.
The malicious dependency [email protected] is never imported in the axios source โ it serves purely as a postinstall hook vehicle. The setup.js dropper uses two obfuscation layers: reversed Base64 with padding substitution, plus an XOR cipher keyed on OrDeR_7077 with constant 333. After deobfuscation, the script fingerprints the host OS via os.platform() and phones home.
C2 infrastructure:
- Domain:
sfrclak[.]com:8000 - IP:
142.11.206.73
Platform-Specific Payload Behavior
Linux: A Python RAT script is fetched from C2, written to /tmp/ld.py, and executed detached from the npm process tree โ meaning it survives after npm install finishes and leaves no obvious npm-attributed process.
macOS: An AppleScript is written to /tmp/6202033 and executed via nohup osascript. It downloads a native binary to /Library/Caches/com.apple.act.mond and runs it via /bin/zsh. The binary overlaps with DPRK-linked BlueNoroff tooling (macWebT internal project name, consistent with the RustBucket campaign’s webT module).
Windows: A VBScript drops a PowerShell second-stage to %TEMP%\6202033.ps1, executes it hidden (-WindowStyle Hidden -ExecutionPolicy Bypass), and self-deletes. Persistent artifact is %PROGRAMDATA%\wt.exe.
Anti-forensics: After execution, the dropper deletes setup.js and replaces package.json with a clean stub renamed from package.md. If you examine node_modules/plain-crypto-js after the fact, the postinstall hook is gone. You need runtime telemetry, not disk forensics.
Why This Matters
Attribution matters here. Google Threat Intelligence Group attributes this to UNC1069, a financially motivated North Korea-nexus actor active since at least 2018, based on the WAVESHAPER.V2 backdoor โ an updated variant of tooling previously tied to this cluster. This isn’t opportunistic โ it’s a targeted operation against developer infrastructure at scale.
The maintainer account compromise was surgical: the attacker obtained a long-lived classic npm access token for jasonsaayman’s account and rotated the registered email to [email protected] before publishing. MFA on npm accounts doesn’t protect against stolen tokens.
The 2-second callout (C2 contact before npm install even finishes) shows operational maturity. If your install logs don’t capture outbound network during npm install, you have a blind spot.
What to Do
Audit your lock files now. Check
package-lock.jsonoryarn.lockfor[email protected],[email protected], or[email protected]. If found, assume compromise.Check for C2 contact. Look for outbound connections to
sfrclak[.]comor142.11.206.73:8000in your network logs. On Linux, also check for/tmp/ld.py; on macOS,/Library/Caches/com.apple.act.mond; on Windows,%PROGRAMDATA%\wt.exe.Hunt the anomalous User-Agent. All platform variants share an identical User-Agent:
mozilla/4.0 (compatible; msie 8.0; windows nt 5.1; trident/4.0)โ IE8 on Windows XP. In 2026 this is unambiguously malicious. Grep your proxy and WAF logs.Rotate credentials on any affected build host. Treat any system that ran a fresh axios install in the window as fully compromised. The RAT has full remote access capability; credential stores, cloud metadata endpoints, and CI secrets are all in scope.
Harden your npm pipeline. Enforce
--ignore-scriptsin CI where you don’t need postinstall hooks. Audit which packages run postinstall scripts (npm install --dry-runshows them). Consider provenance attestation for critical packages.Pin to safe versions.
[email protected]and[email protected]are clean. Lock there until you’ve done a full audit.
The window was short, but axios’s install volume means exposure was real. If you have CI pipelines that ran between midnight and 3 AM UTC on March 31, start there.
IOCs and YARA/Sigma/Suricata rules for WAVESHAPER.V2 are available at the Censys advisory and the GitHub research repo linked in the sources below.
Sources: StepSecurity ยท Google Cloud Threat Intelligence ยท The Record ยท Help Net Security ยท IOC/YARA Gist