StepSecurity documented that once an attacker controls a single NPM account with publish permissions, there is no technical barrier between them and every machine that runs npm install. Their research shows the malicious payload was a full RAT capable of persistent backdoor access, highlighting how the trust model allows compromised packages to reach CI pipelines within minutes of publication.
StepSecurity emphasizes that Axios pulls over 50 million weekly downloads and is embedded so deeply in the JavaScript dependency graph that many teams depend on it transitively without realizing it. The library is pulled in by frameworks, SDKs, and internal tooling across virtually every Node.js shop, meaning the blast radius of a RAT — not just a credential stealer — is unprecedented.
Submitted the StepSecurity report to Hacker News where it received 872 points and 311 comments, signaling the developer community's alarm at the scope of the compromise given Axios's ubiquity as the most widely used HTTP client in JavaScript.
StepSecurity categorizes this as a direct account compromise rather than typosquatting or dependency confusion, calling it the most dangerous category of supply chain attack. They argue it is particularly insidious because developers treat major, well-maintained packages as safe by default — the very trust signals that should indicate safety become the attack surface.
Malicious versions of Axios — the most widely used HTTP client library in the JavaScript ecosystem — were published to NPM carrying a remote access trojan (RAT). The compromise was discovered and documented by StepSecurity, a supply chain security firm, and the report quickly hit 872 points on Hacker News as developers scrambled to check their lockfiles.
Axios pulls over 50 million weekly downloads on NPM, making this one of the highest-impact supply chain attacks in the registry's history. The library is embedded so deeply in the JavaScript dependency graph that many teams don't even realize they depend on it — it's pulled in transitively by frameworks, SDKs, and internal tooling across virtually every Node.js shop on the planet.
The malicious payload was a remote access trojan — not a credential stealer or cryptominer, but a full RAT capable of providing persistent backdoor access to compromised machines. This means any CI/CD runner, developer workstation, or production server that installed the affected versions could potentially be under attacker control.
Supply chain attacks against NPM packages typically follow one of three patterns: typosquatting (publishing `axois` instead of `axios`), dependency confusion (exploiting private/public registry resolution), or direct account compromise. This incident falls into the most dangerous category — the legitimate package itself was tampered with.
The attack vector appears to involve compromise of a maintainer account with publish access to the Axios package. Once an attacker controls a single NPM account with publish permissions, there is no technical barrier between them and every machine that runs `npm install` against that package. NPM's publish-and-propagate model means malicious code reaches CI pipelines within minutes of publication.
What makes this particularly insidious is the trust model. Developers treat major, well-maintained packages as safe by default. Nobody audits every line of `axios` on every update — that's the entire point of package managers. The attacker exploited this trust gap, not a code vulnerability.
The JavaScript ecosystem's dependency depth amplifies the blast radius. A typical Next.js or Express application has hundreds of transitive dependencies. Axios sits in enough dependency trees that even teams who don't directly import it may be affected through packages that do.
The RAT payload is categorically more dangerous than the cryptominers and credential stealers seen in previous NPM compromises. A cryptominer wastes your CPU. A credential stealer grabs tokens. A RAT gives the attacker a persistent, interactive shell on your machine. They can exfiltrate source code, inject backdoors into your builds, pivot to internal networks, or simply wait.
Consider the timeline: from the moment a malicious version is published to when it's detected and yanked, every `npm install` and every CI pipeline run is a potential infection vector. Even conservative estimates suggest thousands of builds ran against the compromised versions before removal. For teams running `npm install` without lockfiles in CI (more common than anyone wants to admit), the exposure window is even wider.
This incident also highlights a structural problem with NPM governance. The registry has over 2 million packages, but the security of the entire ecosystem hinges on a handful of maintainer accounts. NPM requires 2FA for high-download packages, but the definition of "high-download" and the enforcement mechanisms have not kept pace with the actual threat landscape. The ua-parser-js compromise in 2021 was supposed to be the wake-up call. Five years later, the same attack pattern works.
First, the immediate action: check your installed Axios version right now. Run `npm ls axios` in every project. If you're on one of the affected versions, remove it, clear your `node_modules`, and reinstall from a known-good version. Check your CI build logs for the compromise window.
But the deeper lesson is architectural. Pinned versions in `package-lock.json` protect you from future malicious publishes, but they don't help if you pinned the malicious version itself. You need integrity verification — comparing installed package contents against known-good hashes. Tools like `npm audit signatures`, Socket.dev, and StepSecurity's own Harden-Runner can detect anomalous package behavior at install time.
Here's a concrete checklist for your team:
Immediate (today): - Run `npm ls axios` across all projects and CI pipelines - Compare installed versions against the advisory - If affected, treat it as a full incident — rotate secrets, audit access logs, check for persistence mechanisms
This week: - Enable NPM's package provenance verification (`npm audit signatures`) - Add Socket.dev or a similar supply chain scanner to your CI pipeline - Ensure lockfiles are committed and `npm ci` (not `npm install`) runs in CI
This quarter: - Evaluate runtime integrity monitoring for production Node.js processes - Implement SBOM generation for deployed applications - Review which team members have publish access to your internal packages and enforce hardware 2FA
The "fetch" alternative built into modern Node.js (available since Node 18) is worth considering for new projects. It eliminates the Axios dependency entirely for basic HTTP operations. That's not a full replacement — Axios offers interceptors, request cancellation, and automatic transforms that the native fetch API doesn't — but for teams that use Axios as a thin wrapper around `GET` and `POST`, one fewer dependency is one fewer attack surface.
This incident will accelerate two trends already underway. First, package registries will face increasing pressure to implement mandatory provenance attestation — cryptographic proof that a published package was built from a specific commit in a specific repository. NPM has been rolling this out gradually; expect the timeline to compress. Second, the "zero-dependency" movement in the JavaScript ecosystem will gain more converts. Every dependency you add is a trust decision. After Axios, more teams will ask whether that trust is warranted before typing `npm install`.
The broader pattern is clear: software supply chain attacks are not edge cases anymore. They're a primary attack vector, and the tooling to defend against them is still optional, fragmented, and underdeployed. That gap between threat reality and defensive posture is where the next incident will land.
I can't even imagine the scale of the impact with Axios being compromised, nearly every other project uses it for some reason instead of fetch (I never understood why).Also from the report:> Neither malicious version contains a single line of malicious code inside axios itself. Instead, both
PSA: npm/bun/pnpm/uv now all support setting a minimum release age for packages.I also have `ignore-scripts=true` in my ~/.npmrc. Based on the analysis, that alone would have mitigated the vulnerability. bun and pnpm do not execute lifecycle scripts by default.Here's how to
There’s a recurrent pattern with these package compromises: the attacker exfiltrates credentials during an initial phase, then pivots to the next round of packages using those credentials. That’s how we saw them make the Trivy to LiteLLM leap (with a 5 day gap), and it’ll almost certainly be similar
I recommend everyone to use bwrap if you're on linux and alias all package managers / anything that has post build logic with it.I have bwrap configured to override: npm, pip, cargo, mvn, gradle, everything you can think of and I only give it the access it needs, strip anything that is use
Top 10 dev stories every morning at 8am UTC. AI-curated. Retro terminal HTML email.
"Batteries included" ecosystems are the only persistent solution to the package manager problem.If your first party tooling contains all the functionality you typically need, it's possible you can be productive with zero 3rd party dependencies. In practice you will tend to have a few,