How the worm works
SafeDep’s May 2026 disclosure documents a Shai-Hulud variant that compromises npm packages through a self-propagating loop: an infected package harvests maintainer credentials (typically long-lived NPM_TOKEN values stored in CI secrets), then uses those credentials to publish new infected versions of packages the maintainer controls. The worm’s replication mechanism is the credential itself. A lockfile pins you to a specific version, but if the maintainer’s token is compromised, the version you pinned to can be replaced upstream after the fact, or the worm can publish a new version that your next npm install pulls before anyone flags it.
According to SafeDep’s advisory, the campaign reached 314 npm packages. The confirmed baseline from the earlier Mini Shai-Hulud campaign is 170+ packages across PyPI and other registries (per OpenAI’s incident report). Whether the final count is 170 or 314, the mechanism is the same, and the number is secondary to the structural problem it exploits.
Nine months of escalating compromise
The Shai-Hulud family has been active since late 2025, but three incidents in the past two months have compressed the timeline:
March 31, 2026: Anthropic accidentally published 512,000+ lines of Claude Code source code to the public npm registry. Roughly 1,900 TypeScript files were exposed, including internal features like the unreleased “KAIROS” autonomous daemon logic and details of a planned successor to Opus internally called Capybara. Anthropic called it “human error, not a security breach,” which is accurate but misses the point: the file was on npm, resolved by any registry mirror, and cached by downstream proxies before anyone at Anthropic noticed.
May 11, 2026: Attackers hijacked TanStack’s release pipeline to publish 84 malicious versions across 42 packages in a six-minute window. A researcher detected the malicious publishes within 20 minutes, but not before the damage spread. The attack mirrored the Mini Shai-Hulud worm pattern that had already compromised 170+ packages across PyPI and other registries. Two OpenAI employee devices were compromised in the blast radius; OpenAI confirmed theft of “limited credential material” from internal code repositories and is rotating digital certificates.
May 2026: SafeDep’s disclosure of the Shai-Hulud variant targeting npm specifically, with the auto-publish-from-harvested-tokens loop described above.
Why maintainer tokens are the structural weakness
Every one of these incidents traces back to the same root cause: a long-lived credential with publish permissions, stored somewhere a compromise can extract it.
In the TanStack case, the attackers accessed the release pipeline itself, which means they had the same publish authority as the legitimate maintainers. No amount of lockfile pinning helps when the attacker can publish a version that looks identical to a legitimate release, complete with matching git tags, because they’re using the real pipeline.
The Anthropic leak is a different failure mode but the same class of problem: a credential (in this case, a publish action triggered by a human) pushed sensitive content to the registry with no review gate. If Anthropic can accidentally ship 1,900 proprietary files to npm through a process error, any team with a long-lived NPM_TOKEN in GitHub Actions secrets can have that token stolen and used to publish anything.
The common thread: npm’s publish model assumes the credential holder is trustworthy and the credential is secret. Both assumptions are unreliable when tokens are long-lived, stored in CI environments with broad access, and never rotated unless an incident forces the issue.
What provenance attestations fix (and what they don’t)
npm provenance attestations, introduced in 2023, link a published package version to the specific CI build that produced it. The attestation is signed by the CI provider (GitHub Actions, currently) and includes the repository, commit hash, and build configuration. If a package version appears without a provenance attestation when the maintainer normally publishes with one, that’s a signal.
Provenance addresses the impersonation vector: an attacker with a stolen NPM_TOKEN publishing from their own machine rather than the expected CI pipeline. It does not address the compromised pipeline vector (TanStack), where the attacker uses the real CI system. It also does not address the legitimate-but-wrong-publish vector (Anthropic), where the attestation is correctly generated for content that shouldn’t have been published.
Short-lived publish tokens narrow the window further. A token that expires in hours rather than months means a harvested credential is useless within that window, forcing the worm to re-compromise the CI environment for each propagation attempt. This raises the cost of the attack significantly, which is the point: no defense is absolute, but each layer increases the attacker’s required access level and reduces the time available to act.
Checklist
- Audit long-lived
NPM_TOKENsecrets in your GitHub Actions environments. If the token hasn’t been rotated in the past 30 days, rotate it now. - Enable provenance attestations on all package publishes. Add
--provenanceto yournpm publishcommand in CI. Verify the attestation appears on the registry after publish. - Pin dependencies with integrity hashes, not just version ranges.
npm ci(which reads frompackage-lock.json) is the floor, not the ceiling. Subresource integrity checks catch post-publish version swaps. - Monitor SafeDep’s advisory feed and the npm security advisories for the Shai-Hulud variant’s package list. If any appear in your dependency tree, treat it as a credential compromise: rotate the tokens, not just the package versions.
- Short-lived publish tokens should replace long-lived ones. If your CI provider supports OIDC-based token exchange for npm publish (GitHub Actions does), use it. The token lifetime drops from months to minutes.
The worm family is evolving faster than the ecosystem’s default defenses. The fixes are not exotic. They are mostly configuration changes that should have been the default years ago.
Frequently Asked Questions
Does the Shai-Hulud worm family spread beyond npm?
The earlier Mini Shai-Hulud campaign compromised 170+ packages across PyPI and other registries before the npm-specific variant appeared. The token-harvesting mechanism is registry-agnostic: any ecosystem that stores long-lived publish credentials in CI (PyPI API tokens, RubyGems credentials, NuGet API keys) has the same structural weakness. SafeDep’s 314-package count covers npm alone.
What did OpenAI’s response reveal about detection speed limits?
OpenAI isolated two compromised employee machines and rotated digital certificates after the TanStack attack, confirming that credential theft from a supply-chain incident can extend beyond the registry into corporate infrastructure. The attacker published 84 malicious versions in six minutes and detection took 20 minutes. That 14-minute gap between the last malicious publish and detection is enough for automated CI pipelines worldwide to pull compromised packages before any advisory appears.
Can teams using GitLab CI or CircleCI generate npm provenance attestations?
npm provenance attestations are currently limited to GitHub Actions as the signing CI provider. Packages published from GitLab CI, CircleCI, or other platforms cannot generate provenance attestations, making those published versions indistinguishable from attacker-published versions on the registry. Container signing via cosign and sigstore supports multiple CI platforms and a broader set of identity verifications, making it a more portable trust layer for teams not on GitHub Actions.
Does npm’s registry-side propagation delay protect against compromised versions?
npm applies a delayed propagation window to newly registered packages, but not to new versions of existing packages. A compromised maintainer token publishing a new version of an established package bypasses that speed bump entirely because the registry already trusts the package identity. This is why the TanStack attacker published new versions of existing TanStack packages rather than registering new ones.
Are private npm registries safe from this worm?
Only if the publish tokens for the internal registry are isolated from tokens in public-facing CI workflows. If the same GitHub Actions environment that builds a public package also holds credentials for an internal registry, a worm harvesting tokens from the public workflow gains access to the private one. The Anthropic leak illustrates the overprivileged-credential problem: a single publish action exposed 1,900 proprietary files because the credential had no scope restriction.