Safeguard
Supply Chain•

Shai-Hulud npm worm: how self-replication worked

CISA and GitHub describe how the September 2025 npm worm stole credentials and republished itself through maintainers. The mechanics and the defences.

Safeguard Security Team
3 min read

The Shai-Hulud worm spread through npm in September 2025 by stealing a developer's credentials, then using them to publish malicious versions of that developer's other packages. CISA reported over 500 compromised packages, and GitHub removed more than 500 and blocked uploads matching the malware.

The loop, as the agencies describe it

CISA's alert of 23 September 2025 gives the sequence:

  1. A compromised package runs code on install and scans the environment for credentials.
  2. It targets GitHub personal access tokens and cloud API keys for AWS, Google Cloud and Azure.
  3. It sends them to an actor controlled endpoint and uploads credentials to a public GitHub repository named Shai-Hulud.
  4. It authenticates to npm as the compromised developer, injects code into other packages that developer can publish, and publishes new versions.

Each victim becomes the next carrier. GitHub's own post says it was notified on 14 September 2025 and describes the worm as self-replicating, spreading through compromised maintainer accounts with malicious post-install scripts.

Why the design works

Install scripts run with the developer's permissions, often on machines holding long-lived tokens. The worm needs only one maintainer with publish rights to many packages. The more widely a maintainer publishes, the bigger the blast. There is no central command step once it starts.

What CISA advised

  • Review all npm use, including nested dependencies, through lockfiles.
  • Search artifact repositories and caches for affected versions.
  • Pin to releases built before 16 September 2025.
  • Rotate developer credentials.
  • Require phishing resistant MFA on developer accounts, especially GitHub and npm.
  • Block outbound traffic to webhook.site domains and watch firewall logs.
  • Remove unneeded GitHub Apps and OAuth apps, audit repository webhooks and secrets, and enable branch protection, secret scanning and Dependabot security updates.

Controls that break the loop

  • No install scripts by default on developer and CI machines, with an allow list. See the ignore scripts decision guide.
  • Short-lived publish credentials, so a stolen token expires quickly.
  • Trusted publishing, which removes long-lived tokens from the process.
  • Separate machines or containers for publishing, away from everyday work.

What the agencies do not tell us

The sources describe the mechanism and scale, not the first victim or the original entry point, and this post does not guess at either. They also do not say how many developers were affected beyond the package count. Where numbers are missing, use your own lockfiles to answer the one question that matters: did any affected version reach our builds?

Try it yourself

Click through it at your own pace, or open it full screen. Look at how new findings appear after a scan has already passed.

Quick check

Does npm audit catch a worm like this?

Only once the bad versions are recorded as advisories, which takes time. Lockfile pinning and install script controls work earlier.

Why does one maintainer matter so much?

The worm republishes every package its stolen credentials can publish, so one account can seed many packages.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.