How to protect against npm supply chain attacks
A supply chain attack usually starts when an attacker compromises a package maintainer's account, publishes a poisoned version of a trusted package, and waits for automated installs to pull it in before anyone notices. Modern package managers ship built-in defenses against exactly this: cooldowns, install-script blocking, and provenance checks. Most of them are not turned on by default. This guide covers the settings that matter and how to enable them.
The pattern
Nearly every recent npm incident follows the same shape. An attacker phishes or session-hijacks a maintainer,
publishes a new version of a legitimate package with a malicious preinstall/postinstall
script or trojaned code, and that version goes live to the public registry. From there, automated installs do
the spreading: CI pipelines, Dependabot/Renovate updates, and developers running a routine
npm install resolve the newest version and execute the payload, often within hours, long
before the release is detected and yanked. The window between publish and removal is frequently just a few
hours, which is also where your defenses help the most.
The settings that help
Each of these is a built-in package-manager setting. Click through for the exact key, file, and minimum tool version per manager.
Recent incidents
- axios: a poisoned release of the widely used HTTP client, live for roughly three hours (March 2026).
- Shai-Hulud npm worm: a self-propagating worm that compromised packages and stole credentials to publish further (2025).
- TanStack Router/Start: malicious versions of the routing packages, detected within minutes (May 2026).
Do it automatically with DepsGuard
DepsGuard scans your installed package managers, checks whether each of these settings is enabled (and supported by your tool version), and applies the right ones for you, with a diff preview and a backup before any change. Instead of tracking five settings across npm, pnpm, yarn, and bun by hand, you run one command and review what it proposes.
Other good practices
The package-manager settings above harden installs, but they are not the whole picture. A few more habits close common gaps:
- Pin GitHub Actions by commit SHA (not a tag) so a compromised tag can't silently change what runs in CI.
- Use
npm ci/pnpm install --frozen-lockfile/yarn install --immutablein CI so builds install exactly what the lockfile pins. - Review Dependabot/Renovate PRs (read the changelogs, diffs, and provenance) before merging, rather than auto-merging dependency bumps.
- Periodically audit the dependency tree (
npm ls,pnpm why) to understand what you actually pull in transitively.