Résumé

Shai-Hulud is the nightmare the npm ecosystem had long feared: a self-replicating worm. First seen in September 2025 and back in a more aggressive wave around 21-24 November 2025 ("The Second Coming"), it does not just poison one package and wait. When its malware runs in a developer's environment, it harvests every secret it can find, npm tokens, GitHub tokens, cloud keys, then uses those stolen npm tokens to automatically publish itself into other packages the victim maintains, spreading from maintainer to maintainer on its own. The second wave hit more than 25,000 GitHub repositories across roughly 500 compromised accounts, leaked the stolen secrets into public repos, and, if it failed to steal credentials, tried to wipe the victim's home directory. It is the moment supply-chain malware learned to propagate like a biological infection.

How it happened

Named after the sandworm in Dune, Shai-Hulud runs a self-sustaining loop. A developer installs an infected package. The malware, in this wave executing in the pre-install phase so it runs before installation (and before tests or security checks) even finishes, scans the machine for secrets using the TruffleHog scanner and other tools: npm publish tokens, GitHub access tokens, and cloud keys for AWS, GCP, and Azure. It exfiltrates them by creating public GitHub repositories (labelled "Sha1-Hulud: The Second Coming") and dumping the stolen credentials there. Then comes the part that makes it a worm rather than a one-off supply-chain attack: it uses the stolen npm publish token to republish the malware into the first 100 packages that victim maintains, turning each compromised developer into a new launch point for the next round.

The 2.0 wave was nastier than the first. Where the September wave ran from post-install scripts, this one carried a large (over 10 MB), heavily obfuscated payload executed through the Bun JavaScript runtime, moved execution into the pre-install phase, registered the compromised host as a self-hosted GitHub Actions runner (named "SHA1HULUD") for persistent remote access, and added a destructive fallback: if it could not find a working GitHub token, npm credentials, or any exfiltration channel, it attempted to delete the victim's entire home directory.

The damage

The second wave reached more than 25,000 GitHub repositories across roughly 500 accounts and 150-plus organisations, trojanising around 796 npm packages (over a thousand versions) from organisations like AsyncAPI, PostHog, Postman, Zapier, and ENS. AsyncAPI's own postmortem traced its compromise to a three-year-old npm publishing token, a textbook argument for short-lived, scoped credentials. The real payload was secrets at ecosystem scale, thousands of credentials harvested and leaked, each one a potential foothold into a company's cloud or code. The destructive fallback turned it from pure theft into sabotage. It was the centrepiece of a 2025 in which npm supply-chain attacks stopped being isolated incidents and became self-replicating, ecosystem-wide events.

Why Shai-Hulud still matters

Shai-Hulud is a structural escalation: the first major self-propagating npm worm, where a single infected install can cascade across the ecosystem through stolen publish tokens, and where the payload is mass credential theft. The defences target the propagation mechanism: require phishing-resistant 2FA and use short-lived, narrowly scoped publish tokens so a stolen one cannot be reused to self-publish; run installs and CI in isolated, least-privilege environments with no standing cloud credentials; 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. It shares 2025 with the qix chalk and debug compromise, the year npm's trust model truly buckled. And this was not the end of it: in 2026 the worm's code was open-sourced as Mini Shai-Hulud and reused in incidents like the @redhat-cloud-services Miasma compromise, turning a single campaign into a commodity technique. The full arc is traced in the Shai-Hulud lineage.

Comment le corriger

  • Treat every machine that ran an infected package as fully compromised: rotate every credential it could reach, especially npm and GitHub tokens, and revoke the worm's published versions.
  • Search GitHub for the worm's exfiltration repositories to find which of your secrets leaked, and rotate those first; remove any self-hosted runner it registered.
  • Pin to known-good versions, rebuild from a clean lockfile, and check your own published packages for unauthorized releases the worm may have pushed.

Comment l’éviter

  • Require phishing-resistant 2FA and use short-lived, narrowly scoped publish tokens so a stolen token cannot be reused to self-propagate.
  • 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; the worm's entire purpose is harvesting credentials.
  • Pin dependencies and gate updates so a freshly poisoned version cannot flow straight into your builds.

Références

Vulnérabilités liées

Tout Supply chain →