Axios npm Supply Chain Compromise — Malicious axios@1.14.1 and axios@0.30.4 Inject plain-crypto-js@4.2.1 RAT Dropper

Axios npm Supply Chain Compromise (TL-2026-0397), also tracked as Axios npm Supply Chain Compromise, is a critical-severity supply-chain compromise scored CVSS 9.8, first published 2026-04-20. It is attributed to UNC1069 (North Korea) with high confidence, affects Axios axios (npm package), maps to 38 MITRE ATT&CK techniques (T1027, T1027.013, T1033), and is covered by 9 detection rules and 27 indicators of compromise.

Key facts for TL-2026-0397

Threat ID
TL-2026-0397
Also known as
Axios npm Supply Chain Compromise, plain-crypto-js dropper, axios@1.14.1 compromise, axios@0.30.4 compromise, sfrclak.com RAT campaign
Severity
CRITICAL
CVSS
9.8 (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)
Status
MONITORING
Category
SUPPLY_CHAIN
First published
2026-04-20
Last reviewed
2026-04-20
Attribution
UNC1069
Attribution confidence
HIGH
Nation-state nexus
North Korea
Motivation
financial
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
Detection rules
9
Indicators of compromise
27

Malware and tooling in Axios npm Supply Chain Compromise

Malware and tooling: Custom HTTP RAT over sfrclak.com:8000 (campaign id 6202033)

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 dependency plain-crypto-js@4.2.1 whose postinstall hook drops a cross-platform remote access trojan that beacons to sfrclak[.]com:8000. CISA issued a formal alert on 2026-04-20 directing organizations to audit every Node.js build, CI/CD pipeline, and developer workstation that ran npm install or npm update during the approximately 3-hour exposure window, downgrade to axios@1.14.0 or axios@0.30.3, rotate all exposed credentials, and hunt for persistent artifacts such as /Library/Caches/com.apple.act.mond (macOS) and %PROGRAMDATA%\wt.exe (Windows).

How Axios npm Supply Chain Compromise works

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 exit code 0. The dropper then performs anti-forensic self-cleanup: fs.unlink(__filename) deletes setup.js, fs.unlink("package.json") removes the malicious manifest, and fs.rename("package.md", "package.json") installs the clean 4.2.0 stub. Post-infection, npm list plain-crypto-js reports 4.2.0 — not 4.2.1 — because the stub manifest reports the older version number, a deliberate mismatch designed to mislead incident responders who were told to look for 4.2.1. npm audit returns nothing. Only the existence of the node_modules/plain-crypto-js/ directory itself and persistent artifacts (wt.exe, com.apple.act.mond, /tmp/ld.py) remain as evidence. An outer try/catch swallows every error silently: unreachable C2, permission denied, anything — npm install always exits 0.

The releases were live for roughly 2h53m (1.14.1) and 2h15m (0.30.4) before npm''s security response. At approximately 03:15 UTC npm unpublished both axios versions and reverted the latest dist-tag to 1.14.0. At 03:25 UTC npm placed plain-crypto-js on security hold; at 04:26 UTC the registry published the replacement stub plain-crypto-js@0.0.1-security.0 under npm@npmjs.com. Any project that executed npm install or npm update against the resolved registry during the window — or whose CI job or Docker build cached either version — is assumed compromised. StepSecurity Harden-Runner confirmed live callbacks to sfrclak.com:8000 from CI runs (including the backstage/backstage GitHub Actions workflow) during the exposure window. CISA published its formal advisory on 2026-04-20, 20 days after the npm registry response, driving broad enterprise disclosure.

MITRE ATT&CK techniques used in TL-2026-0397

Defense Evasion

T1027 Obfuscated Files or Information; T1027.013 Obfuscated Files or Information: Encrypted/Encoded File; T1036.003 Rename Legitimate Utilities; T1036.004 Masquerading: Masquerade Task or Service; T1070.004 Indicator Removal: File Deletion; T1140 Deobfuscate/Decode Files or Information; T1218 System Binary Proxy Execution; T1564.003 Hide Artifacts: Hidden Window

Discovery

T1033 System Owner/User Discovery; T1082 System Information Discovery

stealth

T1036.005 Match Legitimate Resource Name or Location; T1574.005 Hijack Execution Flow: Executable Installer File Permissions Weakness

Exfiltration

T1041 Exfiltration Over C2 Channel

Execution

T1059.001 Command and Scripting Interpreter: PowerShell; T1059.002 Command and Scripting Interpreter: AppleScript; T1059.003 Command and Scripting Interpreter: Windows Command Shell; T1059.004 Command and Scripting Interpreter: Unix Shell; T1059.005 Command and Scripting Interpreter: Visual Basic; T1059.006 Command and Scripting Interpreter: Python; T1059.007 Command and Scripting Interpreter: JavaScript; T1204.002 User Execution: Malicious File

Command and Control

T1071.001 Application Layer Protocol: Web Protocols; T1102.002 Web Service: Bidirectional Communication; T1105 Ingress Tool Transfer; T1571 Non-Standard Port

Initial Access

T1078.004 Valid Accounts: Cloud Accounts; T1195.001 Supply Chain Compromise: Compromise Software Dependencies and Development Tools; T1195.002 Supply Chain Compromise: Compromise Software Supply Chain

Credential Access

T1528 Steal Application Access Token; T1552.001 Unsecured Credentials: Credentials In Files; T1552.007 Container API

Impact

T1565.001 Data Manipulation: Stored Data Manipulation

Resource Development

T1583 Acquire Infrastructure; T1583.001 Acquire Infrastructure: Domains; T1583.004 Acquire Infrastructure: Server; T1586 Compromise Accounts; T1587.001 Develop Capabilities: Malware; T1608.001 Stage Capabilities: Upload Malware

Affected products and versions in Axios npm Supply Chain Compromise

  • Axios — axios (npm package)
    Vulnerable versions: 1.14.1; 0.30.4
    Fixed in: 1.14.0; 0.30.3
  • nrwise (attacker-controlled) — plain-crypto-js (npm package)
    Vulnerable versions: 4.2.1; 4.2.0
    Fixed in: 0.0.1-security.0 (npm security-holder stub)
  • Node.js ecosystem — Any Node.js application, Electron app, serverless function, or CI/CD build that installed axios@1.14.1 or axios@0.30.4
    Vulnerable versions: Windows (win32); macOS (darwin); Linux; FreeBSD; Android (Termux)

Remediation for Axios npm Supply Chain Compromise

Patches

  • axios@1.14.0 — clean, legitimate, GitHub Actions OIDC-published
  • axios@0.30.3 — clean, legitimate, prior 0.x release
  • npm registry: plain-crypto-js is now a security-holder stub (plain-crypto-js@0.0.1-security.0); any attempt to install any version returns a security notice

Immediate actions

  • Audit every developer workstation, container build, and CI/CD job that executed npm install or npm update between 2026-03-31 00:21 UTC and 2026-03-31 03:15 UTC against any package resolving axios
  • Downgrade axios to 1.14.0 (modern branch) or 0.30.3 (legacy branch); pin exact versions in package.json and re-lock (npm ci) to regenerate package-lock.json from a clean cache
  • Delete node_modules/plain-crypto-js/ from every project; its mere existence is evidence of compromise (legitimate axios has never depended on it)
  • Block outbound connections to sfrclak.com and 185.219.52.237 (if resolved) at perimeter, proxy, and DNS firewall; alert on any historical connection to sfrclak.com:8000
  • Rotate every credential exposed on affected systems: npm tokens, GitHub/GitLab PATs, CI/CD secrets (GITHUB_TOKEN, NPM_TOKEN, AWS/GCP/Azure keys injected into the run), SSH keys, cloud provider keys, and any application secrets accessible from the compromised process context
  • Hunt for persistence: %PROGRAMDATA%\wt.exe (Windows — copy of powershell.exe masquerading as Windows Terminal), /Library/Caches/com.apple.act.mond (macOS RAT binary), /tmp/ld.py (Linux stage-2 Python script), /tmp/6202033 and /tmp/6202033.ps1/.vbs (stager artifacts)
  • Flush npm, Yarn, pnpm, and artifact-repository caches (Verdaccio, Artifactory, Nexus, GitHub Packages) of axios@1.14.1, axios@0.30.4, and any plain-crypto-js version; re-run all CI dependency resolution from a cold cache

Workarounds

  • Pin axios to a clean version in package.json with caret removed (e.g., "axios": "1.14.0" not "^1.14.0") and commit an updated package-lock.json to prevent resolvers from picking up a future malicious bump
  • Install axios with --ignore-scripts flag: npm install --ignore-scripts axios (blocks all postinstall hooks across the dependency tree)
  • Temporarily proxy npm through an internal registry that quarantines new versions for 7+ days before making them resolvable

Longer-term hardening

  • Mandate phishing-resistant MFA (WebAuthn/FIDO2) on all npm maintainer accounts and other package-publishing identities; prohibit long-lived classic npm access tokens
  • Adopt npm Trusted Publisher (OIDC) for every published package; verify _npmUser.trustedPublisher binding in release audits
  • Set ignore-scripts=true in .npmrc on developer machines and in CI; this would have fully neutralized the plain-crypto-js postinstall hook
  • Set min-release-age=7 (or similar 48h–7d delay policy) in .npmrc and in dependency-update automation to avoid consuming packages within their first week
  • Deploy runtime CI/CD hardening (StepSecurity Harden-Runner, GitHub Actions egress controls, or equivalent) to baseline and alert on anomalous outbound connections during build
  • Establish a behavioral baseline for each tool that uses axios; alert on new child processes, container/shell spawning, and novel outbound destinations during npm install
  • Centralize package installation through an internal registry proxy (Verdaccio, Artifactory, Nexus) that enforces allow-list resolution, signature verification, and quarantine of newly-published versions

Weaknesses (CWE) in Axios npm Supply Chain Compromise

CWE-506, CWE-1357, CWE-829, CWE-494, CWE-1104

Timeline of Axios npm Supply Chain Compromise

  • StepSecurity AI Package Analyst and Harden-Runner flag anomalous outbound connections to sfrclak.com:8000 from multiple public GitHub Actions workflows, including the backstage/backstage run — the first public detection of the in-flight attack.
  • At 23:59 UTC, nrwise@proton.me publishes plain-crypto-js@4.2.1 — identical to 4.2.0 except for three added files: postinstall: "node setup.js" hook in package.json, the 4.2 KB obfuscated setup.js dropper, and package.md clean stub for anti-forensic swap.
  • At 05:57 UTC, attacker account nrwise@proton.me publishes plain-crypto-js@4.2.0 to npm — a benign decoy containing bit-for-bit copy of legitimate crypto-js@4.2.0 with no postinstall hook, establishing publishing history to evade zero-history heuristics.
  • Axios project publishes GitHub Issue #10636 (Post Mortem: axios npm supply chain compromise) documenting the compromise of maintainer jasonsaayman''s npm account via a stolen long-lived classic access token.
  • At 03:25 UTC npm initiates a security hold on plain-crypto-js; at 04:26 UTC the registry publishes plain-crypto-js@0.0.1-security.0 under npm@npmjs.com, blocking further installs of any plain-crypto-js version.
  • At approximately 03:15 UTC, npm security unpublishes axios@1.14.1 and axios@0.30.4 and reverts the latest dist-tag to 1.14.0; total exposure window: 2h53m for 1.14.1 and 2h15m for 0.30.4.
  • At 01:00 UTC, the same compromised jasonsaayman account publishes axios@0.30.4 into the legacy 0.x branch, 39 minutes after the 1.x poison, maximizing coverage across both active release lines.
  • At 00:21 UTC, compromised maintainer account jasonsaayman (email changed to attacker-controlled ifstap@proton.me) publishes axios@1.14.1 to npm, injecting plain-crypto-js@^4.2.1 as a runtime dependency and silently dropping the husky prepare hook; no OIDC Trusted Publisher binding and no corresponding GitHub tag or commit.
  • Microsoft Threat Intelligence and Microsoft Defender Security Research Team publish Mitigating the Axios npm supply chain compromise, providing enterprise IOCs, detection guidance, and mitigation recommendations.
  • CISA releases formal cybersecurity alert Supply Chain Compromise Impacts Axios Node Package Manager, urging all organizations to audit CI/CD pipelines and developer workstations, downgrade to axios@1.14.0 or axios@0.30.3, rotate exposed credentials, and block sfrclak[.]com.
  • As of 2026-05-29, the malicious axios@1.14.1/0.30.4 and plain-crypto-js@4.2.1 are unpublished and sinkholed (security-holder stub), neutralizing the immediate vector. But the campaign is now attributed to DPRK Sapphire Sleet, which remains active with follow-on macOS/npm operations, so the actor and supply-chain tradecraft persist.

Sources cited for Axios npm Supply Chain Compromise

Threats related to Axios npm Supply Chain Compromise

Detection coverage for TL-2026-0397

As of 2026-04-20, Threadlinqs Intelligence publishes 9 detection rule(s) for TL-2026-0397 across Splunk SPL, Microsoft KQL and Sigma, covering 27 indicator(s) of compromise. The whole corpus is readable without an account; a free account unlocks full detection query text in Splunk SPL, Microsoft KQL and Sigma; paid tiers add raw indicator values, correlation and the MCP server. Threadlinqs MCP server · View plans.

Further reading

Threadlinqs Intelligence — Real-Time Threat Detection Platform

[ 0 threats ] [ 0 det ] [ CRIT: 0 ] [ HIGH: 0 ]
// threat_feed
$ sort --newest
Showing all threats

Latest Threats