Axios npm Supply Chain Compromise — Malicious axios@1.14.1 and axios@0.30.4 Inject plain-crypto-js@4.2.1 RAT Dropper — Threadlinqs Intelligence
As of 2026-07-02, Axios npm Supply Chain Compromise — Malicious axios@1.14.1 and axios@0.30.4 Inject plain-crypto-js@4.2.1 RAT Dropper is a critical-severity supply chain threat attributed to UNC1069 (North Korea), tracked by Threadlinqs Intelligence with 9 detection rules (Splunk SPL, Microsoft KQL, Sigma) and 27 indicators of compromise.
Threat ID: TL-2026-0397 · Severity: CRITICAL · CVSS: 9.8 · Status: MONITORING · Category: SUPPLY_CHAIN
Attribution: UNC1069 · North Korea · financial
On 2026-03-31, two malicious releases of the Axios HTTP client (axios@1.14.1 and axios@0.30.4) were published to the npm registry from a compromised maintainer account, adding a phantom runtime
On 2026-03-31 at 00:21 UTC the attacker, operating through a hijacked npm account belonging to long-time Axios maintainer jasonsaayman, published axios@1.14.1 to the npm registry. Thirty-nine minutes later at 01:00 UTC the same account published axios@0.30.4 into the legacy 0.x branch. Both releases carry bit-for-bit identical library source, dist bundles, type definitions, README, and CHANGELOG compared to their prior clean versions (1.14.0 and 0.30.3, respectively) — the only substantive diff is a single line added to package.json: the declaration of a new runtime dependency on plain-crypto-js@^4.2.1. The attacker also removed the prepare: husky script, a tell-tale artifact of a manual npm publish that bypassed the Axios project''s GitHub Actions OIDC Trusted Publisher pipeline. Registry metadata confirms the tampering: every legitimate axios@1.x release carries a _npmUser.trustedPublisher GitHub OIDC binding, while axios@1.14.1 was published with a stolen long-lived classic npm access token tied to the attacker-controlled ProtonMail address ifstap@proton.me, with no corresponding commit or tag in the axios GitHub repository.
The plain-crypto-js package was pre-staged to defeat zero-history heuristics. At 2026-03-30 05:57 UTC, attacker account nrwise@proton.me published a benign plain-crypto-js@4.2.0 containing a bit-for-bit copy of the legitimate crypto-js@4.2.0 library (Evan Vosberg, brix/crypto-js) with no postinstall hook. Eighteen hours later, at 23:59 UTC the same day, plain-crypto-js@4.2.1 was published — a file-level diff against 4.2.0 shows exactly three changes: package.json gains a postinstall: "node setup.js" hook, a new 4.2 KB obfuscated dropper file setup.js is added, and a file named package.md containing a clean package.json stub is added for post-execution replacement. All 56 crypto source files remain byte-identical to the decoy, so diff-based analysis against crypto-js finds nothing anomalous in library code. plain-crypto-js is never require()''d anywhere in the axios source — it is a phantom dependency whose sole reason to exist is to fire its postinstall hook.
setup.js is a single minified file using a two-layer obfuscation scheme: sensitive strings (Node module names, OS identifiers, shell commands, the C2 URL, file paths) are stored in an encoded array stq[]; an outer base64/reverse/underscore-to-equals transform feeds into an inner XOR decoder keyed with the string "OrDeR_7077" (whose non-numeric characters resolve to 0 under Number(), producing an effective key of [0,0,0,0,0,0,7,0,7,7]). The dropper''s entry call _entry("6202033") concatenates the decoded base http://sfrclak.com:8000/ with campaign ID 6202033 to produce the C2 URL http://sfrclak.com:8000/6202033. Three platform branches execute:
- macOS (darwin): writes an AppleScript to /tmp/6202033, invokes it via nohup osascript; the AppleScript POSTs packages.npm.org/product0 to the C2, downloads the macOS stage-2 binary to /Library/Caches/com.apple.act.mond (reverse-DNS-styled name abbreviating "Activity Monitor Daemon" to blend with legitimate Apple caches), chmod 770''s it, spawns it via /bin/zsh, and deletes the AppleScript.
- Windows (win32): locates PowerShell via where powershell and copies it to %PROGRAMDATA%\wt.exe (a name that squats on Windows Terminal), creating persistence that survives reinstalls. A VBScript dropped at %TEMP%\6202033.vbs is invoked via cscript //nologo; it curl POSTs packages.npm.org/product1 to the C2, saves the returned PowerShell stage-2 to %TEMP%\6202033.ps1, launches it with -WindowStyle Hidden -ExecutionPolicy Bypass, and self-deletes.
- Linux / other: curl -o /tmp/ld.py POSTs packages.npm.org/product2 to the C2, chains with && nohup python3 /tmp/ld.py in the background, detached from the npm process tree. The trailing & reparents the python3 process to PID 1 (init) as soon as execSync returns.
Every payload runs in the background; execSync returns in under a second so npm install completes normally with e
Weaknesses (CWE)
CWE-506, CWE-1357, CWE-829, CWE-494, CWE-1104
Target sectors: technology, software-development, financial, e-commerce, saas, devops, ci-cd-pipelines, cloud-services, government, healthcare
Target regions: Global, North America, Europe, Asia-Pacific
Detections & IOCs
As of 2026-07-28, this threat has 9 detection rule(s) across Splunk SPL, Microsoft KQL and Sigma, and 27 indicator(s) of compromise. Detection query text and full IOC values are available to authenticated users and programmatically via the Threadlinqs MCP server (Purple tier). View plans.
SUPPLY_CHAIN, CRITICAL, threat intelligence, cybersecurity, T1583, T1583.001, T1583.004, T1586, T1587.001, T1608.001, T1195.001, T1195.002, T1078.004, T1059.001