Axios npm Packages Compromised in Supply Chain Attack

The CyberSec Guru

Updated on:

Axios NPM Packages Compromised

If you like this post, then please share it:

Buy me A Coffee!

Support The CyberSec Guru’s Mission

🔐 Fuel the cybersecurity crusade by buying me a coffee! Why your support matters: Zero paywalls: Keep the content 100% free for learners worldwide, Writeup Access: Get complete writeup access within 12 hours of machine drop along with scripts and commands.

“Your coffee keeps the servers running and the knowledge flowing in our fight against cybercrime.”☕ Support My Work

Buy Me a Coffee Button

TL:DR: Malicious versions of Axios (1.14.1 and 0.30.4) hit the npm registry yesterday (30 March). This release was dropped on npm via compromising Axios maintainer’s account of and replacing the email ID with a proton mail address. 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. As of now, the affected versions have been pulled from npm but any existing packages using those 2 versions or the malware dropper plain-crypto-js package should immediately check IoCs and proceed with recommended steps of removal.

Google has linked the compromise of the widely used Axios npm package to a financially driven threat cluster believed to be tied to North Korea, tracked internally as UNC1069. John Hultquist of Google’s Threat Intelligence Group (GTIG) said the activity aligns with patterns previously observed from this group. He noted that North Korean operators have a long track record of leveraging supply chain intrusions—often with the goal of siphoning cryptocurrency. While the full scope of the incident is still being assessed, the widespread use of Axios means the potential impact could extend across a large number of systems and organizations.

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
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
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.

Researchers are tracking a newly identified backdoor, dubbed WAVESHAPER.V2, which appears to be an evolved iteration of the original WAVESHAPER malware. The earlier variant, written in C++, has been linked to campaigns attributed to UNC1069 – a threat group active since at least 2018 and known for targeting organizations in the cryptocurrency space. According to findings from Mandiant and GTIG, WAVESHAPER.V2 builds on the earlier WAVESHAPER malware, which targeted macOS and Linux systems and has been associated with the UNC1069 threat group.

The original variant relied on a minimalistic command-and-control setup using a raw binary protocol and included basic code-packing techniques to hinder analysis. In contrast, the newer version shifts to JSON-based communication, expands the scope of system data it gathers, and introduces a broader set of capabilities for remote control and execution.

The connection between this latest supply chain compromise and UNC1069 was initially highlighted by Elastic Security Labs, which pointed to notable similarities in behavior and functionality between the two malware strains.

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.

FUNCTION decode_obfuscated(input_string):
# Step 1: Reverse the string
reversed_str = REVERSE(input_string)
# Step 2: Replace "_" with "=" (restore Base64 padding)
base64_ready = REPLACE_ALL(reversed_str, "_", "=")
# Step 3: Base64 decode
decoded_bytes = BASE64_DECODE(base64_ready)
# Step 4: Prepare XOR key
key = "OrDeR_7077"
key_length = LENGTH(key)
output = EMPTY_STRING
# Step 5: Iterate through decoded bytes
FOR i FROM 0 TO LENGTH(decoded_bytes) - 1:
byte = decoded_bytes[i]
# Index formula: (7 * i^2) mod 10
key_index = (7 * i * i) MOD 10
key_char = key[key_index MOD key_length]
# XOR operation with constant 333
# (Assume byte and key_char are integers)
transformed = (byte XOR ASCII(key_char)) XOR 333
# Append character to output
output += CHAR(transformed)
RETURN output

Obfuscation Decode Pseudocode (XOR + Reversed Base64)

Static decoding of all 18 entries reveals: Node.js modules (child_process, os, fs), the C2 URL (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.

Indicators of Compromise (IoCs)

CategoryIndicator TypeValue / ArtifactDescription
NetworkC2 Domainsfrclak.comPrimary command-and-control domain
NetworkC2 URLhttp://sfrclak.com:8000/Base endpoint used for payload delivery
NetworkCampaign URLhttp://sfrclak.com:8000/6202033Campaign-specific payload endpoint
NetworkCampaign ID6202033Identifier used across payload artifacts
Filesystem (macOS)Binary Path/Library/Caches/com.apple.act.mondMalicious binary disguised as Apple daemon
Filesystem (Windows)Executable%PROGRAMDATA%\wt.exeRenamed PowerShell binary (masquerading as Windows Terminal)
Filesystem (Windows)Script%TEMP%\6202033.vbsVBScript loader used for execution
Filesystem (Windows)Script%TEMP%\6202033.ps1PowerShell payload (often deleted post-execution)
Filesystem (Linux)Script/tmp/ld.pyPython-based stage-2 payload
PackagesMalicious Versionaxios@1.14.1Compromised release (tagged latest)
PackagesMalicious Versionaxios@0.30.4Compromised release (tagged legacy)
PackagesMalicious Packageplain-crypto-js@4.2.0Backdoor delivery package
PackagesMalicious Packageplain-crypto-js@4.2.1Backdoor delivery package
npm AccountMaintainerjasonsaaymanCompromised npm account
npm AccountMalicious Emailifstap@proton.meEmail used during compromise
npm AccountLegitimate Emailjasonsaayman@gmail.comOriginal maintainer email
BehavioralExecutionnode setup.jsTriggered via npm postinstall hook
BehavioralTool UsagecurlUsed to download payloads
BehavioralTool UsageosascriptmacOS execution mechanism
BehavioralTool Usagecscript //nologoWindows execution mechanism
BehavioralTool Usagenohup python3Linux background execution
ObfuscationXOR KeyOrDeR_7077Key used for string decryption
ObfuscationEncodingReversed Base64 + XORTwo-layer obfuscation technique
ObfuscationVariablestq[]Encoded string storage array
Anti-ForensicsSelf-Deletionfs.unlink(__filename)Removes installer after execution
Anti-ForensicsFile Swappackage.md → package.jsonHides malicious postinstall evidence

Why GitHub showed nothing

v1.14.0 is still the latest legitimate GitHub release. v1.14.1 was pushed straight to the npm registry with no corresponding tag or commit. Either the attacker had the maintainer’s npm credentials, or they lifted a CI/CD token from a build server. The result is the same: a malicious version that looked, to most automated checks, completely legitimate.

Worse: the maintainers are currently locked out of their own package. According to a public GitHub issue, a collaborator can’t revoke the attacker’s access because the attacker’s permissions appear to exceed the legitimate staff’s. Until npm steps in manually, the situation is basically unresolved.

This is broader than Axios

Socket found two other packages in the same campaign. @shadanai/openclaw buries its malware in a vendored path where scanners typically don’t look. @qqbrowser/openclaw-qbot ships with a pre-populated node_modules folder containing the malicious Axios code already inside, no registry fetch needed.

The maintainer situation is bad

Axios collaborators have said publicly they can’t revoke the attacker’s access. The attacker’s permissions apparently exceed theirs in the npm organization, so remediation attempts are being overridden in real time.

The Axios team has now acknowledged the incident and said they are investigating how the breach happened while parallelly locking down their release pipeline. Initial findings point toward weaknesses in the publishing setup, specifically the coexistence of trusted publishing with an older, long-lived npm token that may have been abused to push malicious updates. It’s also speculated that one of the accounts of the maintainers were compromised and the email ID was changed to a proton mail address. The maintainers are currently trying to revoke existing credentials, enforcing stricter controls around package publishing, and rebuilding the release process to prevent a similar compromise going forward.

Two other packages are already distributing the same malware: @shadanai/openclaw (versions 2026.3.31-2 and 2026.3.32-1) and @qqbrowser/openclaw-qbot@0.0.130, which ships a compromised axios@1.14.1 inside its own node_modules. Both likely picked it up during automated builds.

Who’s affected

Direct: You manually updated to axios@1.14.1 or 0.30.4.

Indirect (and this is the dangerous part): You updated a library that depends on axios with a range like ^1.14.0, and your package manager silently resolved to the malicious version. Most people won’t even know to look.

Compromised PackageVersionMalicious Dependency
Axios1.14.1plain-crypto-js@4.2.1 
Axios0.30.4plain-crypto-js@4.2.1 
plain-crypto-js4.2.1Primary Malicious Payload 

What to do

run npm list axios – if you see 1.14.1 or 0.30.4, you’re affected. Pin to "axios": "1.14.0" (remove the ^ or ~), run npm install axios@1.14.0 --save-exact, delete node_modules and your lockfile, then npm cache clean --force and reinstall.

Rotate credentials. Everything that was in your environment – AWS, GitHub, database passwords. Not optional.

Block sfrclak.com and 142.11.206.73 at the firewall or DNS level. Check CI/CD logs for outbound connections to port 8000.

The Axios codebase itself is fine. This was a distribution attack, not a code problem. v1.14.0 and earlier are safe but if you’ve updated anything in the last day, check before you assume you’re clean.

Buy me A Coffee!

Support The CyberSec Guru’s Mission

🔐 Fuel the cybersecurity crusade by buying me a coffee! Your contribution powers free tutorials, hands-on labs, and security resources.

Why your support matters:
  • Writeup Access: Get complete writeup access within 24 hours
  • Zero paywalls: Keep the content 100% free for learners worldwide

Perks for one-time supporters:
☕️ $5: Shoutout in Buy Me a Coffee
🛡️ $8: Fast-track Access to Live Webinars
💻 $10: Vote on future tutorial topics + exclusive AMA access

“Your coffee keeps the servers running and the knowledge flowing in our fight against cybercrime.”☕ Support My Work

Buy Me a Coffee Button

If you like this post, then please share it:

News

Discover more from The CyberSec Guru

Subscribe to get the latest posts sent to your email!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Discover more from The CyberSec Guru

Subscribe now to keep reading and get access to the full archive.

Continue reading