Summary

Shai-Hulud, in September 2025, was the moment the npm ecosystem's oldest nightmare came true: a worm that spreads by itself. It began with a wave of compromised packages, the most prominent being @ctrl/tinycolor (over two million weekly downloads), and from there it did something no npm attack had done before. When its malware ran on a developer's machine, it hunted for every credential it could find, then used the developer's own npm token to republish itself into all of their other packages automatically, with no attacker involvement, jumping from maintainer to maintainer like an infection. More than 500 packages were compromised, including some from CrowdStrike. It is the first true npm worm (tracked as GHSA-6m4g-vm7c-f8w6 and GHSA-f3v2-259r-f6jc), the template for the more aggressive Second Coming that followed weeks later, and the ancestor of an entire 2026 lineage that ended with the worm's code being open-sourced for anyone to reuse.

How it happened

Named for the sandworm in Dune, Shai-Hulud began on 14 September 2025 with a first burst of compromised packages (the earliest observed was rxnt-authentication; the highest-profile was @ctrl/tinycolor) and then ran a self-sustaining loop. The first packages were seeded with credentials harvested earlier: most analysts trace the seed to the August 2025 s1ngularity attack on the Nx build system, which stole maintainer npm tokens that were never rotated, alongside a parallel phishing campaign using a spoofed npmjs.help domain. (s1ngularity was itself a landmark, the first supply-chain attack to weaponise developers' local AI command-line assistants, invoking the installed tools to crawl the filesystem for secrets.) Same-actor attribution between the two is still treated as an open question rather than settled fact.

When the malware executed in a developer's environment, it harvested that developer's secrets, npm tokens, GitHub personal access tokens, and AWS, GCP, and Azure credentials, using the TruffleHog secret scanner to find them. It exfiltrated those secrets to an attacker webhook and to public GitHub repositories it created, forced some victims' private repositories public, and established persistence by planting a malicious GitHub Actions workflow (shai-hulud-workflow.yml).

The part that made it historic was self-replication. Using the stolen npm token, the malware authenticated to npm and automatically republished trojanized versions of every package the victim maintained, spreading exponentially with no operator involvement at all. Each compromised maintainer became a new launch point, so the worm grew on its own. That is what makes it a worm rather than an ordinary one-shot supply-chain attack, and Wiz called it the first successful self-propagating attack in the npm ecosystem.

The damage

More than 500 packages were caught up in it (security firm Socket catalogued 526 compromised package-and-version entries), including roughly ten packages from the security vendor CrowdStrike, and developer and cloud credentials were harvested at ecosystem scale. The deeper damage was structural: an npm attack that propagates on its own means the list of affected packages grows exponentially rather than staying fixed, which is a fundamentally harder problem to contain. CISA issued a federal alert on 23 September 2025, and the incident forced a permanent change to how npm publishing works. On 9 December 2025 GitHub and npm revoked all legacy classic npm tokens, replaced long-lived tokens with short-lived session tokens, and pushed OIDC-based trusted publishing as the recommended path. That reform is the direct fingerprint of this worm.

The lineage: from one worm to open-source malware

Shai-Hulud did not stop. Weeks later it returned, nastier and at far greater scale, as the Second Coming in November 2025, reaching more than 25,000 repositories and adding a destructive fallback that tried to wipe a victim's home directory. Through early 2026 the family kept mutating, and in May 2026 a group calling itself TeamPCP did the thing that changed the threat permanently: they open-sourced a streamlined variant, Mini Shai-Hulud, publishing the worm's code publicly under the banner "Shai-Hulud: Open Sourcing The Carnage" and even running a contest for the largest attack built with it.

Open-sourcing converted a single-actor campaign into a reusable technique. Within weeks, copycats and unrelated actors were running near-exact copies, and the first major incident built from the leaked code, the @redhat-cloud-services compromise nicknamed Miasma in June 2026, did something the original could not: it published malicious packages carrying valid build provenance by abusing Red Hat's legitimate trusted-publishing pipeline. The worm that began as one actor's tool became a commodity, and attribution collapsed along with it.

Why Shai-Hulud still matters

It is the first self-replicating npm worm, a genuine watershed. Before it, npm supply-chain attacks were one-shot: poison a package and wait. Shai-Hulud weaponised stolen publish tokens to spread itself, turning every compromised maintainer into a spreader, and its descendants then made the technique public property. The defences target that mechanism directly: use short-lived, narrowly scoped publish tokens or OIDC trusted publishing so a stolen token cannot be reused to self-propagate; require phishing-resistant 2FA on maintainer accounts; run installs and CI in isolated, least-privilege environments with no standing cloud credentials; disable install scripts where feasible; and scan for and rotate leaked secrets fast.

How to fix it

  • Treat every machine that ran an infected package as fully compromised: rotate npm, GitHub, and cloud credentials immediately, and revoke the worm's published versions.
  • Search GitHub for the worm's exfiltration repositories and webhooks to find which secrets leaked, and check your own packages for unauthorized republished versions.
  • Remove the malicious GitHub Actions workflow it added for persistence, and rebuild from a clean lockfile pinned to known-good versions.

How to avoid it

  • Use short-lived, narrowly scoped publish tokens or OIDC trusted publishing, so a stolen token cannot be reused to self-propagate, the worm's core mechanism.
  • Require phishing-resistant 2FA on maintainer and publisher accounts.
  • Run installs and CI in isolated, least-privilege environments with no standing cloud credentials, and disable install scripts where feasible.
  • Scan continuously for leaked secrets and rotate fast, and pin dependencies so a freshly poisoned version cannot flow straight into your builds.

References

Related vulnerabilities

All Supply chain →