GHSA-6m4g-vm7c-f8w6
npm · @ctrl/tinycolor, ngx-bootstrap, ng2-file-upload (+500 more)
Résumé
Shai-Hulud, in September 2025, was the moment the npm ecosystem's worst fear 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, and the template for the even more aggressive Shai-Hulud 2.0 that followed weeks later.
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. It was itself downstream of the August 2025 s1ngularity attack on the Nx build system, which had harvested the maintainer credentials that seeded it. When the malware executed in a developer's environment, it harvested that developer's credentials, npm tokens, GitHub personal access tokens, and AWS, GCP, and Azure secrets, using the TruffleHog secret scanner to find them. It exfiltrated those secrets to attacker webhooks and to public GitHub repositories, 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 more than 500 packages (about 526) were ultimately caught up in it.
The damage
More than 500 packages were compromised, including 17 from the security vendor CrowdStrike, and a large volume of developer and cloud credentials was 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, and the incident forced npm and GitHub to overhaul publishing: they revoked all legacy "classic" npm tokens in December 2025, replaced long-lived tokens with short-lived session tokens, and pushed OIDC-based trusted publishing as the recommended path.
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. 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. It returned, nastier and at greater scale, as Shai-Hulud 2.0 two months later.
Comment le corriger
- 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.
Comment l’éviter
- 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.
Références
- https://socket.dev/blog/ongoing-supply-chain-attack-targets-crowdstrike-npm-packages
- https://www.wiz.io/blog/shai-hulud-npm-supply-chain-attack
- https://www.stepsecurity.io/blog/ctrl-tinycolor-and-40-npm-packages-compromised
- https://unit42.paloaltonetworks.com/npm-supply-chain-attack/
- https://github.blog/changelog/2025-12-09-npm-classic-tokens-revoked-session-based-auth-and-cli-token-management-now-available/
Vulnérabilités liées
Tout Supply chain →- CRITICALNPM-SHAI-HULUD-2-2025
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.
- CRITICALNPM-QIX-CHALK-DEBUG-2025
On 8 September 2025, the largest npm supply-chain attack ever by sheer reach hit foundational packages, chalk, debug, ansi-styles, strip-ansi, and 14 more, that together are downloaded over 2 billion times a week. The cause was a single phishing email. A respected maintainer was tricked by a fake "your npm 2FA is expiring" message into handing over his account, and the attackers published poisoned versions of his ultra-popular libraries. The payload was a crypto clipper: browser code that silently swapped any cryptocurrency address a user was sending to with the attacker's. Automated scanners flagged the poisoned versions within minutes and they were pulled within about two hours, and the actual theft came to roughly a thousand dollars, the one piece of good news in an attack that sat, briefly, under nearly the entire JavaScript ecosystem.
- CRITICALGHSA-CXM3-WV7P-598C
On August 26, 2025, attackers exploited a vulnerable GitHub Actions workflow (added Aug 21) susceptible to code injection via a crafted pull-request title to steal Nx's npm publishing token, then published malicious versions of nx (21.5.0, 20.9.0 and others) and several @nx plugins. The malware scanned the filesystem, collected credentials, npm/GitHub tokens, SSH keys and cryptocurrency wallets, and posted them to public GitHub repositories under victim accounts. Dubbed 's1ngularity', it was the first known supply chain attack to weaponize installed AI CLI tools (Claude, Gemini, q) for reconnaissance. The packages were live for about four hours and thousands of secrets were leaked.
- CRITICALNPM-GLUESTACK-REACT-NATIVE-ARIA-2025
Starting June 6, 2025, a threat actor used a leaked npm access token belonging to a maintainer without 2FA to publish malicious versions of 16-17 React Native Aria and gluestack-ui packages with over 1 million combined weekly downloads. The packages were backdoored with obfuscated Remote Access Trojan (RAT) code hidden using whitespace obfuscation, establishing command-and-control infrastructure and persistence on compromised systems. The same payload was tied to a broader campaign also hitting PyPI; end-user impact was limited by the frontend nature of the libraries and a response within 48 hours.
- HIGHCVE-2025-30154
On March 11, 2025 between 18:42 and 20:31 UTC, reviewdog/action-setup@v1 was compromised. Attackers gained enough access to repoint the v1 tag to a malicious fork and inserted a base64-encoded payload directly into install.sh that dumped exposed secrets into GitHub Actions workflow logs. Dependent reviewdog actions (action-shellcheck, action-staticcheck, action-typos and others) were transitively affected. This compromise is believed to have been the entry point that led to the broader tj-actions/changed-files attack; deeper analysis found roughly 218 repositories actually leaked secrets.
- HIGHCVE-2025-30066
Between March 14 and March 15, 2025 the widely used GitHub Action tj-actions/changed-files was compromised. Attackers rewrote existing version tags up to v45.0.7 to point to a single malicious commit, injecting a Node.js function with base64-encoded instructions that downloaded a Python script scanning the GitHub runner's memory. The payload dumped CI secrets (access keys, GitHub PATs, npm tokens, private RSA keys) into publicly readable workflow logs. More than 23,000 repositories used the action; it was patched in v46.0.1.