Package Hijacking
Prerequisites
- Compromised npm maintainer credentials via phishing, credential stuffing, or token leakage
- Target package must have a significant number of downstream dependents to maximize blast radius
Attack Scenarios
Account Takeover and Trojanized Publish
An attacker compromises a maintainer's npm account and publishes a new patch version containing a malicious dependency. A fresh resolution or dependency update can select that patch when a semver range permits it; an existing lockfile can keep the older version. In the March 2026 Axios attack, the attacker changed a primary maintainer account's registered email and published two backdoored versions within a 39-minute window. npm 12 now blocks unapproved dependency install scripts by default, but this does not prevent malicious runtime code in a selected package.
[1][2][3][4][5][6][7][8]npm login --auth-type=legacy
# Using compromised credentials
npm publish
{
"name": "axios",
"version": "1.14.1",
"dependencies": {
"plain-crypto-js": "4.2.1"
}
}
{
"name": "plain-crypto-js",
"version": "4.2.1",
"scripts": {
"postinstall": "node scripts/postinstall.js"
}
}
// The postinstall script downloads and executes a platform-specific
// remote access trojan (RAT) for macOS, Windows, or Linux
Transitive Dependency Amplification
A package deep in the dependency tree is compromised. Because it is a transitive dependency of many popular frameworks, the malicious code reaches thousands of projects that never directly depend on the hijacked package and may not even be aware it exists in their dependency tree.
[1][2][3][4][5][6][7][8]# Check a package's dependencies
PACKAGE=axios
npm view "$PACKAGE" --json | jq '.dependencies'
# To find who depends on a package, check:
# https://www.npmjs.com/browse/depended/axios
# Or use npm.anvaka.com to visualize the dependency graph
Detection
Monitor for Unexpected Version Bumps
Set up alerts for new versions of your critical dependencies. Compare published versions against the project's GitHub releases or changelog to detect unauthorized publishes.
[1][2][3][4][5][6][7][8]npm view axios versions --json | jq '.[-5:]'Lockfile Integrity Verification
Use npm ci instead of npm install to enforce the exact versions and integrity hashes recorded in package-lock.json. Any tampering with the published tarball will cause a checksum mismatch and fail the install.
[1][2][3][4][5][6][7][8]npm ciUse Registry Advisories as a Separate Signal
npm audit submits dependency information to the configured registry's audit endpoint and reports known advisories. It can identify a compromise after an advisory exists, but it is not a general detector for new malicious package behavior.
[1][2][3][4][5][6][7][8]npm audit --audit-level=moderateMitigation
- Enable two-factor authentication (2FA) on all npm maintainer accounts, especially for packages with large install bases
- Use npm ci in CI/CD pipelines to enforce lockfile integrity and detect unexpected changes
- Pin exact dependency versions and review all version bumps before merging
- Monitor npm advisory feeds and subscribe to security notifications for critical dependencies
- Use npm provenance attestations to verify that published packages were built from the expected source repository
- On npm 12, keep dependency install scripts default-denied and approve only reviewed, version-pinned scripts
References
- [1] Supply Chain Attack on Axios npm Package - Socket.dev
- [2] Mitigating the Axios npm Supply Chain Compromise - Microsoft Security Blog
- [3] Inside the Axios Supply Chain Compromise - Elastic Security Labs
- [4] npm Two-Factor Authentication Documentation
- [5] npm Provenance Attestations
- [6] ua-parser-js Hijacking Incident (2021)
- [7] npm audit Documentation
- [8] GitHub - npm 12 Install-Time Security Defaults