Supply Chain

The npm supply-chain attacks every shipper should know in 2026

Why this is everyone's problem

You did not write most of the code in your app. A modern project pulls in dozens of direct dependencies and hundreds of transitive ones — packages depending on packages. That is normal and mostly fine, until one of those packages is compromised. Then the malicious code arrives through a routine npm install, gets bundled, and ships to your users with your name on it. You did nothing wrong except trust the ecosystem everyone trusts.

How a package gets hijacked

The attacker does not break into your project — they break into a package you already use:

  • Account takeover. A maintainer's npm account is phished or credential-stuffed, and the attacker publishes a malicious version.
  • Malicious update. A new version quietly adds code that steals environment variables, tokens or crypto, usually via an install script that runs the moment you install.
  • Self-propagation. The newest twist: malware that, once it runs in a developer's environment, harvests their npm token and pushes itself into their packages, spreading on its own.

The incidents worth knowing

  • event-stream (2018) — the wake-up call: a popular package handed to a new maintainer who slipped in code targeting a specific crypto wallet. It showed how social, not just technical, these attacks are.
  • The qix compromise (2025) — a maintainer account takeover cascaded into widely used packages like chalk and debug, collectively billions of weekly downloads.
  • Shai-Hulud (2025) — the first self-propagating worm in npm, spreading across hundreds of packages by stealing tokens and republishing itself.
  • The 2026 wave — attacks reaching into some of the most-downloaded packages in the registry, proving that popularity is not safety.

The trend is clear: more automated, more self-spreading, aimed at the most trusted packages precisely because they reach the most victims.

The defenses that actually work

Good news: a few low-effort settings would have blunted nearly every recent incident.

  • Commit your lockfile and install with npm ci, so you get exactly the versions you reviewed — not whatever was published five minutes ago.
  • Add a version cooldown. Refuse package versions published in the last several days; most malicious releases are caught and pulled within that window. A 7-day cooldown alone blocks a lot.
  • Do not auto-run install scripts from dependencies. Most compromises execute via postinstall scripts, so disabling automatic script execution and allowlisting only trusted builds removes the main trigger.
  • Pin and review updates rather than upgrading blindly, and watch for advisories on the packages you depend on.

Where a scan fits

The website side of this is fingerprinting: an automated scan identifies end-of-life frontend libraries you are still serving and flags known-compromised packages that show up in what your site ships. It is not a full dependency audit, but it catches the exposed, outdated and known-bad code reaching your users. Scan your site to see what it is currently serving.

Related reading

FAQ

What is the single most effective defense against npm supply-chain attacks?
Commit your lockfile and install with npm ci, combined with a version cooldown that rejects very recently published versions. Together they stop you from automatically pulling a freshly malicious release before it is caught and removed.
How do install scripts make these attacks worse?
Most compromised packages run their malicious code from a postinstall script that executes automatically when you install — before you ever use the package. Disabling automatic script execution and allowlisting only trusted builds removes that trigger.
Can a website scan detect a compromised dependency?
It detects the website-facing part: end-of-life libraries you still serve and known-compromised packages that appear in your shipped code. For full coverage you also need lockfile discipline and dependency auditing in your build pipeline.