Shai-Hulud Worm Poisons 373 npm Packages via CI Cache, Jumps to PyPI

A supply-chain worm called "shai-hulud" compromised 373 package versions across 169 npm names in under six minutes on May 14, before crossing into PyPI. Three independent sources corroborated the incident; a techsnif report confirmed that two OpenAI employee devices were hit via the same TanStack vector — though no user data or production systems were compromised.

What the Source Actually Says

Fireship's technical breakdown traces the exploit to a single CI misconfiguration: TanStack's GitHub Actions workflow used the pull_request_target trigger, which executes fork-sourced PRs under the main repo's permission context. The attacker forked TanStack, opened a PR, and closed it immediately — never reviewed, never merged. That act alone was sufficient to fire the workflow and write a poisoned file into the CI shared cache.

Hours later, an unrelated maintainer merged a legitimate PR. The cache hydrated, the poisoned file executed, and it grabbed TanStack's npm trusted-publishing token — the mechanism specifically built to stop credential-theft attacks. It used that token to publish 84 compromised TanStack packages. Each infected installation then scanned for additional npm tokens and self-propagated, spreading within hours to Mistral AI, UiPath, OpenSearch, Guardrails AI, and Squawk. Python SDKs carried the worm into PyPI. By morning, security firm Aikido was tracking 373 poisoned versions across 169 packages.

Remediation was deliberately neutralized. The worm embedded itself in Claude Code and VS Code so that removing the infected packages would not eliminate it — on relaunch, the editor would re-execute the payload. A background process checked every 60 seconds whether the stolen GitHub token remained valid; expiring the token triggered an immediate home-directory wipe. To blend in, the worm forged commits signed by the Claude Code GitHub app, mimicking AI-generated commits maintainers were already routinely accepting. Matthew Berman's GTIG-sourced analysis contextualizes the incident within a documented rise in AI-accelerated supply-chain threats, with Team PCP's credential-harvesting campaigns identified as lowering the cost barrier for follow-on worms.

Strategic Take

Upgrade to PNPM v1+: minimum-release-age (refuses packages under 24 hours old), block-exotic-subdeps (blocks non-registry transitive deps), and approved-builds (whitelists install scripts) together close the three vectors this worm used. Every pull_request_target workflow in your CI should be audited for fork-permission scope — trusted publishing is not a sufficient defense when the cache itself is the persistence layer.