Axios Got Hijacked and npm Already Knew

March 31, 2026 · 188 words · 1 min read

The axios hijack bypassed CI entirely and the registry showed it plainly.

Two days ago I wrote about dependency cooldowns. axios got hijacked.

My min-release-age=3d config would have blocked both malicious versions (1.14.1 and 0.30.4), but not for the reason I expected.

The attacker didn't publish a new package. They hijacked the primary maintainer's npm account, staged a fake dependency (plain-crypto-js@4.2.1) 18 hours in advance, and published backdoored releases under his real name. The cooldown worked because the staged package was only 18 hours old. Luck, not design.

The actual signal was sitting in the registry the whole time. Every legitimate axios release is published via GitHub Actions with OIDC Trusted Publishers, and the metadata is public:

bash
npm view axios@1.14.0 _npmUser
# { name: 'GitHub Actions', email: 'npm-oidc-no-reply@github.com', trustedPublisher: { id: 'github', ... } }
 
npm view axios@1.14.1 _npmUser
# { name: 'jasonsaayman', email: 'ifstap@proton.me' }

No trustedPublisher, no gitHead, no matching commit or tag in the repo. The OIDC token is ephemeral and workflow-scoped, so it can't be stolen. This release bypassed CI entirely and the registry shows it plainly.

npm has had Trusted Publishers since 2023. For packages that use it, a version without that binding is worth looking at before you install, but nothing in the standard workflow surfaces that check. It's just sitting there.

StepSecurity's full breakdown is worth reading. To check your own packages: npm view <package>@<version> _npmUser.