The Shai-Hulud family of npm worms showed how fragile the JavaScript supply chain can be. The pattern is simple and effective: compromise one maintainer, run malicious code when a package installs, steal tokens and use them to publish infected versions of every other package that maintainer controls.
Waves of this campaign continued through 2026, including a May wave that compromised well over a hundred npm packages and an August wave that reached a very widely used key-value storage library. Combined, affected packages accounted for billions of monthly downloads.
How the attack works
- Initial access – a maintainer's npm token or account is stolen, often through phishing or a previous infection.
- Malicious release – a new version is published with code that runs during
preinstallorpostinstall. - Credential theft – the script searches the machine or CI runner for npm tokens, GitHub tokens and cloud keys.
- Propagation – stolen npm tokens are used to publish infected versions of other packages automatically.
Because it runs at install time, you do not need to import the package for the damage to happen.
Protect your projects
Lock and verify
- Commit your lockfile and install with
npm ciorpnpm install --frozen-lockfilein CI. - Avoid wide version ranges for critical dependencies.
Delay brand-new versions
Most malicious versions are detected within hours or days. A minimum release age means you never install a version published minutes ago.
# pnpm-workspace.yaml
minimumReleaseAge: 1440 # minutes: only install versions at least 24h oldControl install scripts
Lifecycle scripts are the main execution path for these worms. pnpm does not run dependency build scripts unless you allow them. With npm, consider --ignore-scripts in CI and allow scripts only for packages that need them.
Reduce what can be stolen
- Do not keep long-lived npm, GitHub or cloud tokens on developer machines.
- In CI, use short-lived credentials and OIDC trusted publishing instead of stored npm tokens.
- Scope tokens narrowly and rotate them.
Watch continuously
- Enable dependency alerts and a supply chain scanner.
- Review new dependencies before adding them: maintainers, age, download history and install scripts.
For maintainers
- Enable two-factor authentication for publishing.
- Use trusted publishing from CI with provenance.
- Keep the number of people and tokens with publish rights small.
If you think you are affected
- Identify affected package versions in your lockfiles.
- Assume credentials on affected machines and runners are stolen: rotate them all.
- Check for unexpected GitHub repositories, workflows or published versions under your accounts.
- Reinstall from a clean lockfile after the bad versions are removed.
Key takeaways
- Supply chain worms run at install time and steal tokens to spread.
- Lockfiles, minimum release age and controlled install scripts block most attacks.
- Short-lived credentials limit the damage when something gets through.
- If affected, rotate every credential the machine could reach.