Menu
HomeAboutServicesCase StudiesBlogContact
Get Started

Or chat with our AI assistant

The Worm That Forged Its Own Certificate
Back to Blog

The Worm That Forged Its Own Certificate

Security
May 16, 2026
6 min read
A

AWZ Team

Security Engineering

On May 11 at 19:20 UTC, someone opened a pull request against TanStack's router repository. By 19:26, 84 malicious npm packages had been published across 42 @tanstack/* packages. By midnight, the worm had spread to Mistral AI, UiPath, and dozens of other maintainers. By May 14, OpenAI confirmed that two employee devices were compromised.

This is the story of how a self-propagating npm worm called Mini Shai-Hulud became the first supply chain attack in history to forge valid SLSA Build Level 3 provenance certificates for its malicious packages.

The Attack That Worked at Every Level

The worm, attributed by StepSecurity to the threat group TeamPCP, chained three vulnerabilities that none alone would have been sufficient for.

Step one: the Pwn Request. An attacker named their fork zblgg/configuration to avoid appearing in fork-list searches. They committed malicious code under the fabricated identity [email protected], prefixed with [skip ci] to suppress automated checks, then opened PR #7378 titled "WIP: simplify history build" against TanStack/router. The workflow used pull_request_target, which runs in the base repository's security context. The fork's code had access to the base repo's cache scope and GITHUB_TOKEN.

Step two: cache poisoning. The malicious vite_setup.mjs from the fork did not exfiltrate anything. It poisoned the pnpm package store under the exact cache key that the release workflow would later look up. The 1.1 GB cache entry was saved at 11:29 and persisted undetected for nearly eight hours. The cache scope is shared across pull_request_target runs and base-branch pushes, creating the cross-boundary poisoning window.

Step three: OIDC token extraction. When the legitimate release workflow triggered at 19:15, the poisoned cache binaries ran during the build phase. They used a technique documented in the March 2025 tj-actions/changed-files compromise. They located the Runner.Worker process, read its address space from /proc/*/mem, extracted the OIDC token, and posted directly to registry.npmjs.org authenticated as the legitimate TanStack release workflow. The workflow's intended publish step never executed. The malicious publish happened anyway, authenticated with a valid OIDC token and valid SLSA provenance.

What Valid SLSA Provenance Actually Means Now

This is the part that keeps security engineers awake. The Sigstore attestations on the compromised @tanstack/* versions are legitimate. They correctly certify that the packages were built and published by release.yml running on refs/heads/main in the TanStack/router repository. All of that is true.

SLSA provenance attests that a package was built by a specific repository's GitHub Actions run. It does not attest that the workflow was authorized to run, that it executed from a protected branch, or that the commit triggering it was legitimate.

The worm published packages with valid provenance because it hijacked the build pipeline itself. Sigstore verified the build process correctly. What Sigstore could not verify was that the code being built was safe.

This is the first documented case of a malicious npm package carrying valid SLSA provenance. It will not be the last.

The Payload Was Sophisticated

The 2.3 MB router_init.js file was smuggled into each compromised tarball's root, a file not declared in the package's files field. Each package received an injected optionalDependencies entry pointing to a GitHub dependency that looked official but was controlled by the attacker.

The payload used three layers of obfuscation. A Fisher-Yates substitution cipher with PBKDF2-SHA256 at 200,000 iterations. Eleven AES-256-GCM encrypted payloads requiring the Bun runtime to decrypt. The campaign's internal name, recovered from deobfuscation: EveryBoiWeBuildIsAWormyBoi.

After decrypting, the worm performed a systematic sweep of every major credential plane. GitHub Actions environment variables. AWS credentials via IMDSv2. HashiCorp Vault tokens. Kubernetes service account tokens. SSH private keys. GCP metadata. Over 100 credential paths on Linux and macOS.

It also targeted ~/.claude/projects/*.jsonl, reading Claude Code session history files containing code and any credentials that appeared in prior sessions.

Persistence: Uninstall Is Not Enough

The worm wrote copies of itself into Claude Code hooks (.claude/settings.json re-executes the payload on every tool event). It wrote VS Code workspace tasks (.vscode/tasks.json runs on folder open). A developer who ran npm install on an affected version could be re-compromising their environment every time they opened their editor.

The dead man's switch was worse. A systemd service on Linux and a LaunchAgent on macOS polled api.github.com/user with the stolen token every 60 seconds. If the token was revoked, it ran rm -rf ~/. Destroying the user's home directory.

Security researcher carlini identified this in a GitHub issue comment within hours of the attack. The remediation order is critical: disable the monitoring service before rotating credentials.

The worm propagated through npm's own API, querying registry.npmjs.org/-/v1/search?text=maintainer:<username> and republishing packages under stolen OIDC identities. By end of day, at least 170 affected packages had been documented.

OpenAI Was the Headline

OpenAI confirmed on May 14 that two employee macOS devices were compromised through the TanStack attack. The company announced that older versions of its macOS desktop apps would stop receiving updates and may not function after June 12, 2026. Affected employees had limited credentials exposed. No customer data or training systems were impacted, according to OpenAI's incident report.

The real story is not that OpenAI got hit. The real story is that any organization using npm packages from a compromised maintainer would have been equally exposed. The worm did not target OpenAI specifically. It spread through the dependency graph. OpenAI happened to be in the blast radius.

What You Need to Do Right Now

If your team uses @tanstack/* packages, check whether any affected versions reached your environments. The compromised hashes are documented in Snyk's security database and GitHub advisory GHSA-g7cv-rxg3-hmpx.

Before rotating any credentials, disable the persistence mechanisms. Stop and remove the systemd or LaunchAgent monitoring service. Remove .claude/ and .vscode/ persistence files. Only then rotate npm publish tokens, GitHub tokens, AWS credentials, and any secrets that lived on affected machines.

Review your GitHub Actions OIDC configuration. If any npm package uses trusted publishing without branch and workflow pinning, fix that now. The vulnerable configuration trusts the entire repository. The secure configuration pins to a specific workflow and branch.

Add release-age cooldowns to your package managers. A seven-day minimum release age would have fully protected against this specific attack.

And most importantly, do not trust SLSA provenance alone. The worm proved that valid attestations do not mean safe packages. Behavioral analysis at install time is the complementary control that would have caught these artifacts within minutes.

We covered supply chain attack response patterns in our post about the Mercor LiteLLM compromise and the Axios npm attack. The playbook is the same even when the technique changes. If you are not sure your pipeline is vulnerable to this class of attack, talk to us. We have been tracking the Shai-Hulud toolchain since September 2025 and know exactly what to check.

Tags

TanStack
Supply Chain Attack
npm
OpenAI
Mini Shai-Hulud
GitHub Actions
Security

Share this article

Related Articles

Your LLMs Are Leaking Data

Your LLMs Are Leaking Data

Stanford's 2025 AI Index shows 78% of companies use AI in at least one business function. Almost none of them have data governance controls built for how LLMs actually process information.

SecurityMay 8, 20265 min read
Someone Bought 30 WordPress Plugins Just to Backdoor Them

Someone Bought 30 WordPress Plugins Just to Backdoor Them

A buyer spent six figures on Flippa for a portfolio of 30 WordPress plugins, planted a PHP deserialization backdoor in August 2025, and waited eight months before activating it across hundreds of thousands of sites.

SecurityApril 16, 202618 min read

Stay Updated

Get the latest insights on AI, automation, and digital transformation delivered to your inbox.