Historical intelligence backfill. This assessment covers reporting originally published on 2025-12-09 and was added to the RWP archive on 2026-09-07.
Shai-Hulud 2.0 turned npm install into a worm and CI into the amplifier
Microsoft's December 2025 guidance covered the second Shai-Hulud wave — preinstall payloads, stolen developer tokens, and self-propagation across npm — after a November outbreak that hit hundreds of packages.
Bottom line up front
CONFIRMED Shai-Hulud 2.0 (also called sha1-hulud / "the second coming") was a self-propagating npm supply-chain campaign. Microsoft's 9 December 2025 guidance is the registry seed. Primary mechanics corroborated by GitHub, Wiz, and Expel: malicious preinstall (scripts such as setup_bun.js / bun_environment.js), credential harvesting (TruffleHog-class scanning), exfiltration into attacker-controlled GitHub repos, then republishing the victim's other packages with a bumped patch version. Wiz later reported a long tail into late December, Fortune 100 exposure, and persistence via private registries and cached packages after npm purged public copies. Expel cited hundreds of packages and tens of thousands of GitHub repositories in the second wave's blast radius.
This is not a single poisoned library. It is a worm whose fuel is developer and CI secrets. Historical backfill of 9 December 2025 Microsoft guidance; first 2.0 packages around 24 November 2025 per Wiz/Rescana timeline; added 7 September 2026.
What happened
Wave 1 in September 2025 showed the brand. Wave 2 in late November moved execution to npm install time (preinstall), added Bun-runtime bootstrapping, harvested a wider secret set, and — GitHub stresses — grew nastier in CI: different behavior on build agents, self-hosted runner registration as a C2-ish foothold, privilege tricks on certain agents, destructive options.
Microsoft documented compromised packages carrying setup_bun.js in package.json, malicious commits including identity spoofing, and cloud-connected developer/CI impact. Wiz's later "snip the tail" work showed why "we deleted it from npm" was not containment: internal mirrors kept serving poison, and an infected OpenVSX extension kept re-seeding until a clean version shipped.
Microsoft's 9 December post, read in 2026, also notes a May 2026 "Mini Shai-Hulud" spanning npm and PyPI. That is later evidence the playbook survived. It is not merged as the same incident.
Why it mattered
Every shop that runs npm install in CI on a runner with cloud keys is a publishing authority waiting to happen. The worm's genius is economic: steal the maintainer token, infect the next popular package, repeat. Users who did nothing wrong still ingested a transitive dependency.
Wiz's Fortune 100 fraction, even as a vendor-observed metric, is enough to put this above routine typosquatting.
Who / what was affected
CONFIRMED npm ecosystem; developer laptops and CI; GitHub tokens, cloud keys (AWS/GCP/Azure counts appear in secondary roundups). Named ecosystems in coverage include packages associated with AsyncAPI, Zapier, PostHog, Postman, and others — treat vendor victim lists as REPORTED and verify against your lockfiles rather than copying a hall of shame.
UNKNOWN complete package census at any one hour; attribution.
OT: not claimed. A manufacturer whose HMI toolchain pulls npm is an IT supply-chain victim, not a PLC exploit.
Technical context
Hunt/contain, not exploit:
preinstall/postinstallthat fetch Bun or second-stage JS you did not write- unexpected
setup_bun.js,bun_environment.js - GitHub repos created as secret dumps
- npm publishes from CI identities that should only consume
- lockfile diffs that bump patch versions you did not request
ATT&CK: T1195 supply chain, T1552 credentials in files, T1078 valid accounts.
Exploitation / threat status at the time
CONFIRMED worm in the wild November–December 2025; npm and GitHub disruption actions; long tail via caches.
REPORTED 700+ packages / 25k repos in some December roundups — use as magnitude, not as your inventory.
ASSESSED (high): any org that did not rotate npm, GitHub, and cloud credentials after installing affected versions still had a persistence problem in January.
What defenders should have done
- Pin and verify lockfiles; block lifecycle scripts in CI where the build can use prefetched tarballs (
ignore-scriptsplus a reviewed allow-list). - npm tokens: granular, not classic; no publish from developer laptops if CI can do it with OIDC.
- Assume breach of developer GitHub and cloud keys if a poisoned install ran; rotate, then rotate the rotation credentials.
- Flush private npm proxies and developer caches; Wiz's long tail is specifically this failure.
- Review GitHub for unexpected public repos and for self-hosted runners you did not register.
What we know now
GitHub's roadmap post and Wiz's 30 December "tail snip" show containment was a month of ecosystem labor, not a Tuesday patch. May 2026 Mini Shai-Hulud is proof of copycats or continuation. Unit 42's later ChainDrop analysis (IT-095) is a related worm class — keep it a separate post unless facts collapse.
RWP assessment
Confidence: High on mechanics and that CI secrets were the blast-radius multiplier. Moderate on any one public package count.
If your software-supply-chain program is SCA letter grades and no token governance, you are grading the library while the worm publishes as you.
Defensive actions
- Disable install scripts in CI by default.
- OIDC publishing, short-lived tokens, mandatory 2FA on npm maintainers.
- Emergency tabletop: "transitive preinstall just ran on the runner that has AWS."
- Re-scan every lockfile from 24 November 2025 through year-end, not just production.
Sources
- Microsoft Threat Intelligence — Shai-Hulud 2.0 guidance for detecting, investigating, and defending
- GitHub — Strengthening supply chain security: Preparing for the next malware campaign
- Wiz — Snipping the Long Tail of Shai-Hulud 2.0
- Expel — Stories from the SOC: The second coming of Shai Hulud