Poisoned Axios: npm Supply Chain Attack Delivers a Cross-Platform RAT

Axios Supply Chain Attack npm RAT
83 million downloads a week. One compromised account. A trojan that erases itself.
Mauto 6 min

Imagine going to the supermarket, grabbing your usual jar of Nutella — the one you’ve been buying for ten years, always the same, always right there on the shelf — and discovering that someone snuck something far less tasty inside it overnight. That’s exactly what happened to Axios.

If you’re a JavaScript developer, Axios needs no introduction. If you just landed from Mars: it’s the most widely used HTTP client library in the JS ecosystem, with over 83 million weekly downloads. Yes, you read that right. Eighty-three million. Per week.

And someone put a trojan in it.

How a Supply Chain Attack Works (Explained to a 10-Year-Old)

Before diving into the technical details, a quick word on the concept. A supply chain attack is when a bad actor doesn’t attack your system directly — maybe it’s well-defended — but instead attacks something you use to build your system. A library, a build tool, an npm package.

It’s like poisoning the water at the source instead of poisoning every single glass. Much more efficient. Much more unsettling.

In Axios’s case, the attacker didn’t find a vulnerability in the code. They did something simpler and more devastating: they compromised the npm credentials of the project’s primary maintainer, a user named jasonsaayman.

The Attack Timeline: 39 Minutes to Hit Two Branches

What stands out about this attack isn’t just the target, but the surgical precision with which it was carried out. StepSecurity researchers reconstructed the sequence:

  • March 30, 2026, 05:57 UTC — A “clean” version of the package plain-crypto-js@4.2.0 is published. This makes the author look legitimate and avoids raising suspicion.
  • March 30, 2026, 23:59 UTCplain-crypto-js@4.2.1 is published, this time with the malicious payload inside.
  • March 31, 2026, 00:21 UTC — Using the compromised jasonsaayman account, axios@1.14.1 is published, injecting plain-crypto-js@4.2.1 as a dependency.
  • March 31, 2026, 01:00 UTC — Same treatment for axios@0.30.4.

Between the first and second infected version: 39 minutes. Both release branches hit. Three separate payloads pre-built for three different operating systems. The whole thing staged 18 hours in advance. This wasn’t a bored script kiddie — there was a plan.

The Malware: A RAT That Erases Itself

The infection mechanism is elegant, in the most disturbing sense of the word. plain-crypto-js@4.2.1 contains no visible malicious code — it’s all hidden inside a postinstall script. When npm installs the package, it automatically runs this script: an obfuscated Node.js dropper called setup.js.

The dropper detects the operating system and picks the appropriate attack path:

On macOS, it runs an AppleScript payload that fetches a trojan binary from the C2 server (sfrclak.com:8000), saves it to /Library/Caches/com.apple.act.mond (note the deliberate choice of a system folder to blend in), makes it executable, and launches it in the background. Then it deletes itself.

On Windows, it locates the PowerShell binary, copies it to %PROGRAMDATA%\wt.exe (disguised as Windows Terminal), writes a VBScript to a temp folder, and executes it to fetch a PowerShell RAT from the same C2. Downloaded file? Deleted immediately.

On Linux, it uses Node.js’s execSync to download a Python RAT script via curl, save it to /tmp/ld.py, and run it in the background with nohup. Same script, different stage.

All three paths contact the same C2 but on different endpoints (/product0 for macOS, /product1 for Windows, /product2 for Linux), allowing the server to respond with the platform-appropriate payload.

Once installed, the macOS RAT — written in C++ — does one thing and does it well: every 60 seconds it beacons back to the remote server and waits for commands. It can run shell commands, enumerate the filesystem, launch additional payloads, and — of course — terminate itself when needed.

The Forensic Cleanup: The Part That’s Actually Scary

The most sophisticated part of the attack isn’t the RAT itself, but what happens after installation. The malware performs three cleanup operations:

  1. Removes the postinstall script from the installed package directory
  2. Deletes the package.json that references the postinstall hook
  3. Renames package.md to package.json

That package.md is a file bundled inside plain-crypto-js containing a clean package.json manifest — no postinstall hook anywhere. After execution, if anyone goes to inspect the package folder, they find an innocent manifest. Zero traces. As if nothing ever happened.

As researcher Ashish Kurmi of StepSecurity put it: every trace was designed to self-destruct. That’s not dramatic language — it’s an accurate technical description.

How Do I Know If I Was Hit?

First: check which version of Axios is installed across your projects. If you see 1.14.1 or 0.30.4 anywhere, you’re potentially exposed.

Then check whether these files exist on the system:

  • macOS: /Library/Caches/com.apple.act.mond
  • Windows: %PROGRAMDATA%\wt.exe
  • Linux: /tmp/ld.py

If you find any of these artifacts, assume you’re compromised and start rotating all credentials on the machine. Not “maybe”, not “let’s evaluate” — rotate them. All of them.

The safe versions to downgrade to are 1.14.0 and 0.30.3. Also remove plain-crypto-js from your node_modules folder. And block outbound traffic to sfrclak[.]com at the firewall level.

If you use CI/CD — and who doesn’t — audit your pipeline logs for any runs that may have installed the affected versions.

Not Just Axios: The Ripple Effect

As if that weren’t enough, researchers at Socket identified two additional npm packages distributing the same malware:

  • @shadanai/openclaw (versions 2026.3.28-2, 2026.3.28-3, 2026.3.31-1, and 2026.3.31-2)
  • @qqbrowser/openclaw-qbot (version 0.0.130)

The latter is particularly interesting because it ships a tampered copy of axios@1.14.1 directly inside its own node_modules folder. When npm processes this vendored version of Axios, it installs plain-crypto-js and triggers the entire malicious chain.

The real Axios has exactly three dependencies: follow-redirects, form-data, and proxy-from-env. Any other dependency is a red flag.

The Moral of the Story (If There Is One)

This attack is a brutal reminder that supply chain security is the number one problem in modern software development. It doesn’t matter how secure your own code is: if one of the dependencies you rely on gets compromised, so do you.

A few things worth thinking about:

The account takeover was the real issue. The attacker didn’t exploit a vulnerability in Axios’s code. They obtained a long-lived npm access token for the maintainer’s account. Probably stolen from some leak, maybe from a breach on another platform where jasonsaayman reused a password. Enable MFA on npm. Right now.

The postinstall hook is a massive attack surface. Every time you run npm install, you’re potentially executing arbitrary code from whoever published a package. Tools like StepSecurity and Socket monitor npm packages specifically for this. Consider them, especially in production environments.

Version pinning ≠ absolute security. If you had axios@^1.14.0 in your package.json, you likely installed 1.14.1 on your next npm install. Exact version pinning (1.14.0 without the ^) helps, but it’s not a complete solution — you also need to verify checksums.

83 million downloads a week. Think about it. If this attack had stayed active even a few hours longer, the number of compromised systems could have been astronomical. The relatively quick discovery is good news. But “relatively quick” still means people were able to install this thing for hours.

As always in cybersecurity: it’s not a matter of if it’ll happen, but when. And when it does, better to be prepared.

Update Axios, audit your pipelines, and good luck to all of us.

Copiato