âš Active Incident Published: March 31, 2026
Category: Supply Chain Security
Severity: Critical
🚨 Immediate Action Required If your environment ran npm install on axios between 00:21 UTC and 03:29 UTC on March 31, 2026, you may have deployed a Remote Access Trojan. Treat affected systems as fully compromised — do not attempt to clean in place. Rebuild from a known-good state and rotate all credentials.
Background: Why Axios Is a Big Target
Axios is the de facto standard HTTP client for JavaScript. It runs in browsers, Node.js backends, serverless functions, CI/CD pipelines, mobile apps via React Native, and virtually every modern cloud environment. With somewhere between 83 and 300 million weekly downloads, it is one of the top ten most downloaded packages on the entire npm registry — present in roughly 80% of cloud and code environments globally.
That scale is exactly what made it a high-value target. A brief window of compromise on a package this embedded doesn’t require thousands of victims — the math works in the attacker’s favor from the first minute the poisoned version is live.
What We Know (Confirmed)
The Attack Timeline
Mar 30
05:57 UTC
Stage 1 — Clean Decoy Publishednpm user nrwise@proton.me publishes plain-crypto-js@4.2.0 — a clean copy of the legitimate crypto-js library. Its purpose: establish a brief publishing history so later versions wouldn’t appear zero-history to security scanners.
Mar 30
23:59 UTC
Stage 2 — Malicious Payload Activatedplain-crypto-js@4.2.1 is published containing a postinstall hook pointing to an obfuscated dropper script (setup.js). Socket’s automated scanner flags it within 6 minutes.
Mar 31
00:21 UTC
Stage 3 — Axios 1.x Poisonedaxios@1.14.1 is published from the compromised jasonsaayman account (email changed to ifstap@proton.me). The only change from the legitimate release: plain-crypto-js@4.2.1 added as a runtime dependency. No axios source code was touched. No corresponding GitHub tag exists.
Mar 31
01:00 UTC
Stage 4 — Axios 0.x Also Poisonedaxios@0.30.4 is published via the same compromised account — poisoning the legacy 0.x branch just 39 minutes after the 1.x release.
Mar 31
~03:15 UTC
Stage 5 — npm Removes Malicious VersionsBoth axios@1.14.1 and axios@0.30.4 are unpublished. The latest tag reverts to 1.14.0. The malicious versions were live for approximately 2h 53m and 2h 15m respectively.
Mar 31
04:26 UTC
Stage 6 — plain-crypto-js Tombstonednpm publishes a security-holder stub (plain-crypto-js@0.0.1-security.0). Any attempt to install any version of plain-crypto-js now returns a security notice.
How the Dropper Works
The malicious setup.js dropper (4,209 bytes) fires automatically via npm’s postinstall lifecycle hook the moment npm install runs. It uses two layers of obfuscation to defeat static analysis: reversed Base64 encoding with padding character substitution, then an XOR cipher with the key OrDeR_7077 and a constant of 333.
Once decoded, the dropper fingerprints the OS, phones home to the attacker’s C2 server at sfrclak.com:8000, retrieves a platform-specific second-stage payload, executes it, then self-destructs — deleting setup.js and replacing its own package.json with a clean decoy. The entire process takes approximately 15 seconds. A developer inspecting node_modules afterward finds no obvious sign anything happened.
Platform-Specific RAT Payloads
macOS: RAT artifact dropped at:/Library/Caches/com.apple.act.mond
Windows: RAT artifact dropped at:%PROGRAMDATA%\wt.exe
Linux: RAT artifact dropped at:/tmp/ld.py
What Systems Were Exposed
| Environment Type | Exposure Vector | Risk Level |
|---|---|---|
| Developer workstations | Manual npm install or update during the window | Critical |
| CI/CD pipelines | Automated builds using caret ranges (^1.14.0) re-resolving | Critical |
| Docker build environments | RUN npm install in Dockerfiles without pinned lockfiles | Critical |
| Cloud / serverless build runners | Fresh installs on ephemeral workers during the window | High |
| Projects using caret ranges | ^1.14.0 or ^0.30.0 auto-resolve to malicious version | High |
| Transitive consumers | @shadanai/openclaw and @qqbrowser/openclaw-qbot ship poisoned axios | Medium |
Wiz Security observed actual RAT execution in approximately 3% of affected environments — meaningful at this scale.
What’s Being Assumed (Unconfirmed)
How the Account Was Compromised
Early maintainer statements and community discussion point to a likely combination of a long-lived npm token that was never rotated and insufficient use of Granular Access Tokens and trusted publishing controls. The attacker changed the account’s registered email to ifstap@proton.me before publishing, locking out the legitimate owner. The exact initial access vector — phishing, credential stuffing, or a leaked token — has not been publicly confirmed.
Attacker Attribution and Motive
No group has claimed responsibility as of publication. The operational sophistication — pre-staging a dependency 18 hours in advance, building three platform-specific payloads, implementing anti-forensic self-deletion, and poisoning both release branches within 39 minutes — suggests a well-resourced actor. Some researchers have noted similarities to the TeamPCP campaign that targeted Trivy, LiteLLM, and Telnyx just days prior, though a direct link has not been confirmed.
Full Scope of the RAT’s Capabilities
The second-stage payload’s full capability set is still under analysis. What the RAT does post-installation — keylogging, credential harvesting, lateral movement, persistent access — remains under active investigation by multiple security firms.
Current Aftermath & Status
Active / Developing
The malicious versions were removed from npm within roughly three hours. The legitimate axios@1.14.0 is clean and is the current recommended version. The primary maintainer has issued a public statement confirming the account compromise, with remediation efforts underway including token revocation and pipeline hardening.
Additional poisoned packages have been identified: @shadanai/openclaw (versions 2026.3.28-2, -3, 2026.3.31-1, -2) and @qqbrowser/openclaw-qbot@0.0.130. Security identifiers: GHSA-fw8c-xr5c-95f9 and MAL-2026-2306.
How to Detect If You Were Compromised
Step 1 — Check Your Dependency Tree
# Check lockfiles for the malicious dependencygrep -r “plain-crypto-js” ./package-lock.jsongrep -r “plain-crypto-js” ./yarn.lock# Check node_modules (presence means dropper ran)ls node_modules/plain-crypto-js# Confirm axios versioncat node_modules/axios/package.json | grep ‘”version”‘# BAD: “version”: “1.14.1” or “version”: “0.30.4”# GOOD: “version”: “1.14.0” or prior clean release
Step 2 — Hunt for RAT Artifacts by OS
# macOSls -la /Library/Caches/com.apple.act.mond# Windows (PowerShell)Test-Path “$env:PROGRAMDATA\wt.exe”# Linuxls -la /tmp/ld.py
Step 3 — Audit CI/CD Build Logs
Review pipeline logs for the window of 00:21–03:29 UTC on March 31, 2026. Any build that resolved axios@1.14.1 or axios@0.30.4 should have its runner and all accessed secrets treated as compromised.
Step 4 — Search Network Logs for C2 Callbacks
Search DNS, proxy, and firewall logs for outbound connections to sfrclak.com or sfrclak.com:8000. Any hit confirms RAT execution.
âš Important Note on Self-Deletion The dropper self-destructs after execution. The absence of plain-crypto-js in your node_modules does not mean you are safe. If your lockfile or build logs show it was installed during the exposure window, assume compromise regardless of current file system state.
Remediation Steps
- Pin axios to 1.14.0 in
package.jsonand regenerate your lockfile - Run
npm audit— check for GHSA-fw8c-xr5c-95f9 or SNYK-JS-PLAINCRYPTOJS-15850652 - If a RAT artifact is found — rebuild from a known-good state. Do not clean in place
- Rotate all credentials accessible from the compromised environment: npm tokens, AWS/GCP/Azure keys, SSH private keys, CI/CD secrets, .env values
- Audit Docker images built during the exposure window and repromote from a clean base
- Block
sfrclak.comat the firewall/DNS level and alert on any historical hits - Move to Granular Access Tokens on npm, enable 2FA enforcement, and implement trusted publishing via CI rather than personal long-lived tokens
Indicators of Compromise (IOC Summary)
| Type | Indicator | Description |
|---|---|---|
| Package | axios@1.14.1 | Malicious npm release — 1.x branch |
| Package | axios@0.30.4 | Malicious npm release — 0.x branch |
| Package | plain-crypto-js@4.2.1 | Malicious dropper dependency |
| Domain | sfrclak.com | C2 command-and-control server |
| Port | :8000 | C2 callback port |
| File (macOS) | /Library/Caches/com.apple.act.mond | Dropped RAT artifact |
| File (Windows) | %PROGRAMDATA%\wt.exe | Dropped RAT artifact |
| File (Linux) | /tmp/ld.py | Dropped Python RAT |
| npm Account | jasonsaayman / ifstap@proton.me | Compromised publisher identity |
| npm Account | nrwise@proton.me | Created malicious dependency |
| GHSA | GHSA-fw8c-xr5c-95f9 | GitHub Security Advisory ID |
| MAL ID | MAL-2026-2306 | Malware registry identifier |
The Bigger Picture
This attack follows a pattern that has accelerated over the past 18 months: compromise a legitimate maintainer credential, publish a minimal change that doesn’t touch source code, and rely on the ecosystem’s implicit trust of registered packages. What sets this incident apart is the operational precision — pre-staging, dual-branch poisoning, triple-OS payload delivery, and anti-forensic self-deletion. A roughly three-hour window still produced confirmed RAT execution in approximately 3% of observed affected environments.
For defenders, this is a strong argument for lockfile-based installs (npm ci over npm install), npm provenance attestation, runtime egress monitoring on build runners, and mandatory MFA with token rotation policies for any npm publisher account tied to a high-download package.
References & Further Reading: How to Detect and Protect Against CVE-2026-20952 and CVE-2026-20953, CVE-2026-2441: Google Chrome CSS Use-After-Free Zero-Day
#SupplyChain#npm#Axios#RAT#SOC#IncidentResponse

Leave a Reply
You must be logged in to post a comment.