Back to Blogs
Axios Was Backdoored for Two Hours and Gave Hackers Full Control of Your Machine
securitynpmjavascriptsupply-chainwebdev

Axios Was Backdoored for Two Hours and Gave Hackers Full Control of Your Machine

On March 31, 2026, the most-downloaded JavaScript HTTP client was backdoored for two hours. Here is what actually happened, why vibe coders are especially at risk, and exactly what you need to do right now.

0 views
0

At 00:21 UTC on March 31, 2026, someone published axios@1.14.1 to npm. It had a backdoor in it.

Not in the axios source code , that part was clean. The attacker was smarter than that. They slipped in a single fake dependency called plain-crypto-js@4.2.1, and that dependency ran a postinstall script that downloaded a cross-platform remote access trojan to your machine the moment you ran npm install.

If your CI pipeline ran in that window, assume compromise. If you pulled a fresh install between 00:21 and 03:29 UTC, your credentials may already be somewhere you do not want them.

This is what modern supply chain attacks look like. And no, your AI code editor did not warn you about it.

What Actually Happened

The attacker did not find a vulnerability in axios's code. They went after something softer: the npm account of @jasonsaayman, axios's primary maintainer. Somehow they got his credentials , likely through a phishing campaign or a leaked token , and changed the registered email on his account to a Proton Mail address they controlled.

With maintainer access, they published two poisoned versions:

  • axios@1.14.1 at 00:21 UTC
  • axios@0.30.4 at 01:00 UTC

Both versions looked normal from the outside. Same source code. Same API. The only difference was in package.json, where the attacker added plain-crypto-js@4.2.1 as a runtime dependency , a package that had been staged 18 hours earlier with a clean 4.2.0 version to give it a brief legitimate history on the registry.

When npm resolved the dependency tree, it pulled plain-crypto-js, hit its postinstall hook, and executed setup.js. That was the dropper.

CVE Reference

This incident is tracked as SNYK-JS-AXIOS-15850650 (the poisoned axios versions) and SNYK-JS-PLAINCRYPTOJS-15850652 (the malicious dependency). Neither is available on npm anymore, but if you installed during the window, the damage is already done.

The dropper used two layers of obfuscation , reversed Base64 with padding substitution, followed by an XOR cipher with the key OrDeR_7077. Once decoded, it reached out to sfrclak[.]com:8000 and downloaded a platform-specific second-stage payload:

  • macOS: A compiled C++ binary dropped to /Library/Caches/com.apple.act.mond, spoofing an Apple background daemon
  • Windows: PowerShell copied to %PROGRAMDATA%\wt.exe disguised as Windows Terminal, with a Registry Run key for persistence across reboots
  • Linux: A Python RAT written to /tmp/ld.py and launched via nohup so it survived the terminal session

All three variants beaconed to the C2 server every 60 seconds. All three could execute arbitrary commands, enumerate your filesystem, and load additional payloads. The macOS and Windows variants supported in-memory binary injection.

After execution, the dropper deleted itself, removed the postinstall entry from package.json, and swapped in a clean manifest file. If you inspected node_modules/plain-crypto-js after infection, you would find no trace it was ever there.

Elastic Security Labs noted significant overlap between the macOS payload and WAVESHAPER, a C++ backdoor attributed by Mandiant to UNC1069, a North Korean threat actor. That detail should sit with you for a minute.

Vibe Coders: You Are the Target

Here is the uncomfortable truth. This attack was not aimed at security engineers who review lockfiles before deploying. It was aimed at the people who type npm install and move on.

There is a generation of developers right now , and I include myself in this at times , who use AI tools to generate entire applications, copy-paste npm install commands from Stack Overflow threads or AI chat responses, and deploy before they have read the README. This workflow is fast. It ships. It is exactly what "vibe coding" describes.

But fast iteration without security awareness is not a feature. It is an attack surface.

The axios attack worked because CI/CD pipelines across thousands of organizations were set up to run npm install (not npm ci) without pinned versions, without lockfile enforcement, and without --ignore-scripts. Three hours. Two malicious package versions. And any pipeline that pulled a fresh install during that window was fully compromised the moment npm finished running.

The Scale Problem

Axios has over 100 million weekly downloads. Even a two-hour malicious window represents an enormous blast radius. The attacker hit both the 1.x and 0.x release branches within 39 minutes of each other. This was not accidental. It was planned.

The vibe coding ethos is real and it produces real things. But the tools you use , npm, GitHub Actions, Vercel deploys , are part of a supply chain. You do not have to become a security expert overnight. But you do have to stop treating npm install like a consequence-free action.

How to Check If You Are Affected

Run this right now.

bashbash
# Check for the compromised axios versions
grep -E '"axios"' package-lock.json | grep -E '1\.14\.1|0\.30\.4'
 
# Check for the malicious dependency
npm ls plain-crypto-js
 
# Search node_modules directly
find node_modules -name "plain-crypto-js" -type d

If you are on Bun:

bashbash
grep -E 'axios' bun.lock | grep -E '1\.14\.1|0\.30\.4'
grep 'plain-crypto-js' bun.lock

Also look for RAT artifacts on the system itself:

PlatformArtifact
macOS/Library/Caches/com.apple.act.mond
Windows%PROGRAMDATA%\wt.exe
Linux/tmp/ld.py
NetworkOutbound connections to sfrclak[.]com or 142.11.206.73:8000

If you find any of these, the machine was compromised. Do not attempt to clean it. Rebuild from a known snapshot.

How to Fix It and Stay Protected

If you are not affected, great. Here is what to do anyway.

Pin axios to a known safe version

Any version except 1.14.1 and 0.30.4 is clean. In your package.json, pin to 1.14.0 or earlier. Do not use a version range that would silently pull the next release on install.

jsonjson
{
  "dependencies": {
    "axios": "1.14.0"
  }
}

Switch CI from npm install to npm ci

npm install can update your lockfile. npm ci enforces it. This single change would have protected most organizations from this attack.

bashbash
# In your CI pipeline, replace:
npm install
 
# With:
npm ci

Add --ignore-scripts to CI installs

The entire attack lived in a postinstall hook. Disabling lifecycle scripts in CI eliminates this class of attack entirely.

bashbash
npm ci --ignore-scripts

Be aware this breaks packages that legitimately need postinstall steps (native addons, for example). Test your build after adding this flag.

Block plain-crypto-js at the registry level

Add plain-crypto-js to your organization's package blocklist. In npm Enterprise and many private registry setups, you can explicitly deny packages.

Run a security scan today

bashbash
npm install -g snyk
snyk auth
snyk test

Snyk's database includes entries for both CVEs. If you have any projects that pulled the affected versions, it will flag them.

If you already found the compromised version:

  1. Isolate the machine immediately. Do not rotate credentials from the affected system , the RAT may be watching.
  2. Rotate everything from a clean machine. API keys, SSH keys, GitHub tokens, cloud credentials, npm tokens. Revoke and reissue, do not just change values.
  3. Check your CI/CD logs for March 31, 2026 UTC. Every pipeline that ran npm install in that window needs investigation.
  4. Block egress to sfrclak[.]com and 142.11.206.73 at the network level.
  5. Rebuild the environment. Compromised machines cannot be trusted.
If In Doubt, Rotate

A stolen API key is the attacker's best tool. Rotate constantly, not just when you think you have been hit. The cost of rotating credentials is hours. The cost of a breach is days, sometimes a company.

The Bigger Pattern Nobody Wants to Talk About

This is not the first time a legitimate npm package was hijacked through a compromised maintainer account. It happened to ESLint's Prettier plugin. It happened to ua-parser-js in 2021. It happened to the Shai-Hulud campaign, which compromised over 600 packages in a single operation.

The common thread is not a clever 0-day or an advanced technique. It is social engineering plus an ecosystem that gives postinstall scripts full system access by default.

You should also know that two other packages were shipping the same payload: @qqbrowser/openclaw-qbot@0.0.130 and @shadanai/openclaw versions 2026.3.31-1 and 2026.3.31-2. The same C2 infrastructure. The same RAT. The axios compromise may have been the main show, but it was not the only stage.

The open source ecosystem runs on trust. Maintainers give their time, often for free, to build tools that power billions of dollars of software. That trust is also the attack surface. Protecting it requires more than good intentions , it requires 2FA on npm accounts, hardware keys for publishing access, and lockfile hygiene that most projects still do not have.

And maybe, just maybe, before you vibe-code your next startup on a stack of unaudited dependencies, take ten minutes to check what you are actually installing.


Did this affect your setup, or did you catch it in time? Drop a comment below , I am genuinely curious how many CI pipelines pulled the bad version and what the incident response looked like. And if you have a workflow change that keeps your supply chain cleaner, share it. Everyone here builds with the same ecosystem and we all benefit from each other's hard lessons.


Parth Sharma

Author Parth Sharma

Full-Stack Developer, Freelancer, & Founder. Obsessed with crafting pixel-perfect, high-performance web experiences that feel alive.

Discussion0

Join the conversation

Sign in to leave a comment, like, or reply.

No comments yet. Start the discussion!