Skip to content
kushal.st

The Axios Supply Chain Attack of 2026: Why Your package.json is a Security Time Bomb

3 min read Security, Supply Chain, npm, JavaScript

Originally published on Medium - read it there ↗

In the early hours of March 31, 2026, the JavaScript ecosystem was rocked by one of the most sophisticated supply chain attacks in recent history. Axios, the ubiquitous HTTP client with over 100 million weekly downloads, was compromised.

This wasn’t a “bug” in the code. It was a targeted hijacking of the lead maintainer’s NPM account, leading to the release of malicious versions - axios@1.14.1 and axios@0.30.4 - that turned developer machines and CI/CD pipelines into gateways for state-sponsored malware.

The Anatomy of the Attack

The attack was a masterclass in “phantom dependencies.” The hackers didn’t change a single line of Axios’s logic. Instead, they added one silent line to the package.json file: a dependency on a package called plain-crypto-js.

plain-crypto-js was a “typosquat” - a malicious package designed to look like the legitimate crypto-js. Once installed via a simple npm install, it triggered a post-install script that:

  1. Identified the OS: Detected whether the machine was running Windows, macOS, or Linux.
  2. Deployed a RAT: Downloaded a platform-specific Remote Access Trojan (RAT).
  3. Wiped its Tracks: Deleted the installation artifacts to evade forensic detection.

Because Axios is often a transitive dependency (a dependency of a dependency), thousands of projects pulled in this malware automatically without developers ever typing the word “axios.”

The “Silent” Vulnerability: Carets (^) and Tildes (~)

The primary reason this attack spread so rapidly boils down to two tiny symbols in your package.json: the caret (^) and the tilde (~).

  • The Caret (^1.14.0): Tells NPM to automatically grab the latest “minor” or “patch” version (e.g., it will upgrade to 1.14.1, 1.15.0, etc.).
  • The Tilde (~1.14.0): Limits updates to “patch” versions only (e.g., it will upgrade to 1.14.1, but not 1.15.0).

In this case, any developer with "axios": "^1.14.0" in their file who ran npm install on March 31st was automatically served the poisoned 1.14.1 version. The very feature designed to keep us secure with “automatic bug fixes” became the delivery mechanism for the virus.

How to Fix Your package.json Right Now

To safeguard your projects, you must move toward Version Pinning. This means removing the “auto-update” symbols for critical, high-traffic libraries.

Step 1: Remove the Symbols

Change your dependencies to exact versions.

Bad (Vulnerable):

"dependencies": {
  "axios": "^1.14.0"
}

Good (Secure):

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

By removing the ^, you are telling the package manager: “Do not download anything other than exactly version 1.14.0 unless I manually change this number.”

Step 2: Use npm ci Instead of npm install

In your deployment pipelines and local setups, use npm ci (Clean Install). Unlike npm install, which might try to update versions based on your carets, npm ci ignores the package.json ranges and installs the exact tree recorded in your package-lock.json.

Step 3: Disable Scripts for Third-Party Code

The Axios hack relied on a postinstall script. You can prevent these scripts from running by using:

npm install --ignore-scripts

Beyond the Quick Fix: A New Security Mindset

While “pinning” versions requires more manual work to stay updated, the 2026 Axios hack proved that convenience is the enemy of security. If you suspect you were affected:

  • Search your lockfiles for plain-crypto-js or axios: 1.14.1.
  • Immediately rotate all secrets (AWS keys, SSH keys, API tokens) that were present on that machine.
  • Wipe and rebuild the environment. A RAT (Remote Access Trojan) is designed to persist even after you “delete” the package.

The era of trusting “latest” is over. It’s time to take control of your dependency tree, one exact version at a time.