Security Digest · Nov 24, 2025 · Supply-chain compromise · Library
Shai-Hulud 2.0: npm Worm Hits PostHog, Zapier, Postman
Nov 2025 self-spreading npm worm trojanized ~500-800 packages and leaked secrets to 25k+ GitHub repos. Long removed; only Nov 21-27 2025 installs need checks.
Our verdict
Check exposure
The worm is long dead on npm, but any machine or CI runner that installed a trojanized version between Nov 21 and Nov 27, 2025 should be treated as having leaked every secret it could reach.
Who must act: Teams whose lockfiles, CI logs or artifact caches show a flagged version installed in late November 2025, and anyone who finds a 'Sha1-Hulud' repo or SHA1HULUD runner under their GitHub account.
Who can relax: Projects whose lockfiles were unchanged across Nov 21-27, 2025, or that installed only from builds or mirrors older than that window, were not exposed.
- Affected
- About 500-800 npm packages (counts vary by researcher), e.g. posthog-node 4.18.1, 5.11.3, 5.13.3
posthog-js 1.297.3, posthog-react-native 4.11.1, @posthog/ai 7.1.2, @posthog/cli 0.5.15
Packages under @asyncapi, @postman, @zapier, @ensdomains, @voiceflow and Browserbase scopes (see Wiz/Aikido IOC lists) - Fixed in
- Malicious versions removed from npm; maintainers published clean follow-up versions
Pin to versions published before Nov 21, 2025 or later clean releases - CVSS
- Not scored
- EPSS
- n/a
- CISA KEV
- Not listed
- Exploitation
- Exploited in the wild
- Severity
- Critical
What to do
- Grep lockfiles and CI logs for flagged package versions and for setup_bun.js / bun_environment.js
- Search GitHub (user and org) for repos described 'Sha1-Hulud: The Second Coming' and for self-hosted runners named SHA1HULUD
- Delete .github/workflows/discussion.yaml and any unknown workflows or branches
- Rotate npm, GitHub, AWS, GCP, Azure and CI secrets reachable from affected hosts, from a clean machine
- Rebuild affected workstations and runners from clean images; clear npm/pnpm caches
- Disable install scripts in CI and adopt a minimum release age for new versions
How to check if you are affected or compromised
- find / -name 'setup_bun.js' -o -name 'bun_environment.js' -o -name 'truffleSecrets.json' 2>/dev/null
- grep -E 'posthog-node@(4.18.1|5.11.3|5.13.3)|posthog-js@1.297.3' package-lock.json pnpm-lock.yaml yarn.lock
- GitHub search: repos with description 'Sha1-Hulud: The Second Coming' owned by your accounts
- Org settings: self-hosted runners named SHA1HULUD; workflow file .github/workflows/discussion.yaml
What happened#
On November 24, 2025, a second, larger version of the self-replicating npm worm first seen in September began spreading. Aikido first detected it at 03:16 UTC in go-template and 36 @asyncapi packages. PostHog packages followed within an hour, then Postman. Zapier, ENS Domains and Browserbase packages were also hit. Unlike the September wave, which ran in postinstall, this variant runs in preinstall. A loader, setup_bun.js, installs the Bun runtime and runs an obfuscated payload, bun_environment.js.
The payload runs TruffleHog over the machine, pulls cloud secrets from config files, environment variables and metadata services, and dumps AWS Secrets Manager, GCP Secret Manager and Azure Key Vault. It then publishes the results to a new public GitHub repo with a random name and the description "Sha1-Hulud: The Second Coming", in files such as cloud.json, environment.json and truffleSecrets.json. With any npm token it finds, it republishes up to 100 of the victim's own packages; the September wave's cap was 20. Wiz also documented a backdoor: the infected machine is registered as a GitHub self-hosted runner named SHA1HULUD, and a .github/workflows/discussion.yaml workflow runs commands taken from discussion posts. If the malware cannot authenticate to GitHub or npm, it wipes the user's home directory.
The worm got in through PostHog's CI. Per PostHog's post-mortem, a pull_request_target workflow ran a script from untrusted pull-request code. On November 18 that leaked a bot token with broad write access, and the attacker used it to push a workflow that exposed the npm publishing token.
Who is affected#
Researchers count the packages differently: Aikido counted 492 packages with about 132 million monthly downloads, and Wiz counted roughly 700-800. Wiz counted more than 25,000 exfiltration repos and found @postman/tunnel-agent in about 27% of the cloud environments it scanned, and posthog-node in about 25%. Concrete bad versions include posthog-node 4.18.1, 5.11.3 and 5.13.3 (OSV MAL-2025-190925) and posthog-js 1.297.3. Use the IOC lists from Wiz and Aikido rather than guessing.
Do you really need to act?#
If you were exposed, yes. The malicious versions were live for hours to a few days, and Wiz saw leaked AWS keys and GitHub PATs abused by November 26, including downloads of private source code. The exposure is narrow, though: you needed to resolve a flagged version during the November 21-27, 2025 window, with install scripts enabled. A lockfile committed before then that did not change during the window means you were not exposed. The attack landed just before npm's planned December 9 revocation of classic tokens, part of the hardening GitHub announced in September 2025. For most teams today, this is a one-time audit, not an ongoing emergency.
What to do now#
- Check lockfile history for flagged versions, for example
git log -p --since=2025-11-20 --until=2025-11-28 -- package-lock.json pnpm-lock.yaml yarn.lock | grep -E 'posthog|asyncapi|postman|zapier|ensdomains', then match against the vendor IOC CSVs. - In GitHub, look for repos you own with the "Sha1-Hulud" description, self-hosted runners named
SHA1HULUD, unknown branches, and anydiscussion.yamlworkflow. Remove them. - From a clean machine, rotate npm tokens, GitHub PATs and OAuth apps, SSH keys, and AWS/GCP/Azure keys, plus any CI secret an affected runner could read.
- Rebuild affected hosts from clean images instead of cleaning them in place. Delete
node_modulesand runnpm cache clean --force(andpnpm store prune). - Run
npm ci --ignore-scriptsin CI where possible. Set a minimum release age in pnpm or yarn, and move publishing to trusted publishing (OIDC). - Audit workflows that use
pull_request_targetand check out PR code. That is the exact pattern that started this wave.
How to tell if you were hit#
Host artifacts: setup_bun.js, bun_environment.js, an unexpected Bun install, and output files such as truffleSecrets.json or cloud.json. PostHog also suggests searching npm logs for "shai" or "preinstall" entries. On GitHub, signs include public repos you did not create, commits referencing "hulud", workflow runs that upload a secrets artifact and then delete their branch, and the SHA1HULUD runner. In cloud audit logs, look for secret-manager reads and IAM changes from unfamiliar IPs after November 24, 2025.
Timeline#
- — After the first Shai-Hulud wave, GitHub announces npm token and 2FA hardening.
- — A PostHog bot token leaks through a
pull_request_targetworkflow. - — Malicious versions appear starting about 03:00 UTC; Aikido and Wiz raise the alarm; PostHog revokes tokens by 09:30 UTC.
- — GitHub starts mass removal of exfiltration repos; Wiz observes leaked credentials being abused.
- — Wiz reports about 15 malicious versions still on npm.
Sources
Original sources first: vendor and project advisories, CVE and government records, the discoverers’ write-ups. Every claim above links to one of these. See how the Security Desk works.
Original and primary sources
- Aikido — Shai Hulud strikes again, hitting Zapier and ENS Domains aikido.dev
- Wiz — Sha1-Hulud 2.0 ongoing supply chain attack wiz.io
- PostHog — Shai-Hulud supply chain attack post-mortem posthog.com
- OSV — MAL-2025-190925 Malicious code in posthog-node osv.dev
- GitHub Blog — Our plan for a more secure npm supply chain github.blog