Key Takeaways
– 84 malicious npm packages published across 42 TanStack repositories on May 11, 2026
– OIDC token stolen through a `pull_request_target` workflow flaw that most teams still haven’t patched
– 518 million downloads accumulated before containment
– Code-signing certificates exfiltrated by 19:26 UTC, six minutes after the first malicious publish
– OpenAI forced certificate rotation June 12, leaving a six-week exploitation window wide open
—
The TanStack npm supply chain attack on May 11, 2026 didn’t start with a clever exploit. It started because a CI workflow trusted the wrong trigger. Eighty-four malicious package versions went live across 42 TanStack projects in six minutes. Two OpenAI developer machines were compromised before anyone at TanStack knew something was wrong. Code-signing certs were already headed to attacker infrastructure.
Five hundred and eighteen million downloads later, the npm checkmark still glowed green on every single one of them. Google’s GTIG “Big Sleep” report documented the pattern the same day.
How TanStack’s Signing Keys Got Stolen
No brute force.
No phishing. Nobody guessed a password.
The attackers used TanStack’s own publishing machinery against it.
The weak link was a GitHub Actions workflow configured with `pull_request_target`.
That trigger’s been flagged in GitHub’s own security documentation for years. Security researchers have been yelling about it since at least 2023. Honestly, if your CI still runs on it, you’re not alone. But you should fix that tonight.
Here’s the sequence. Cross-fork cache poisoning. The attackers injected a payload into a workflow run on their own fork. The runner loaded it, grabbed the poisoned cache, and with it the OIDC token npm uses for trusted publishing. Every malicious package the worm pushed after that carried a valid TanStack cryptographic signature. Not forged. Not spoofed. Genuinely signed by the real key.
Eighty-four versions. Six minutes.
Every one verified and trusted by npm’s own infrastructure.
Why pull_request_target Is Still Dangerous
This is the part I can’t stop thinking about.
CI runners cache aggressively. Build artifacts. Dependency layers. Shell scripts that set up the environment.
The whole point is speed.
But here’s the catch.
The cache key is tied to the workflow, not to a specific commit hash.
So here’s what an attacker does. Push a poisoned commit to their fork. Trigger the workflow. The cache stores the payload. Next time a maintainer opens a pull request or merges to main, the runner fetches that same cache. Dirty.
Loaded with whatever the attacker left in there.
And `pull_request_target` makes it worse as it inherits the base repository’s permissions.
Not the fork author’s. The maintainer’s. Write access to secrets. Deployment tokens. The full pipeline.
Didn’t need to breach TanStack’s network. Didn’t need credentials. Just needed TanStack’s CI to pull attacker code into the same process that signs packages for 518 million downloads.
Side note: I spent about forty minutes last week auditing our own Actions workflows after reading this.
Found two workflows with `pull_request_target` that also cached build artifacts. Fixed both. Took longer to find them than to fix them.
The Six-Week Certificate Window
OpenAI issued a mandatory certificate rotation on June 12.
Forty-two days after the initial compromise.
That’s the window that scares me more than the initial breach.
Code-signing certificates have a useful lifespan. The attackers grabbed valid certs, rotated them before they expired. And kept signing malicious payloads that passed every validation check on user machines. For six weeks, anything signed with those certificates looked legitimate.
If you ship desktop software with signed binaries — doesn’t matter what kind — you need a response plan for certificate theft.
OpenAI just demonstrated what happens when you don’t have one ready.
Six minutes to compromise. Six weeks to clean up. That ratio should bother you.
What You Should Actually Do Tonight
Not tomorrow. Not next sprint. Tonight.
Rotate everything on any machine that ran `npm install` against a TanStack package on or after May 11. SSH keys. GitHub personal access tokens. npm credentials. AWS access keys. Anything that lived in a `.env` file or a shell profile. Don’t batch this into a Jira ticket.
Pin TanStack dependencies to versions published before May 11.
Or pull the SHA directly from TanStack’s security advisory and verify the hash matches what’s in your lockfile. A bare `npm install` on an affected version is not safe until you’ve confirmed integrity.
Audit your GitHub Actions for `pull_request_target`.
Found it? Check whether that workflow writes to the filesystem or caches artifacts. If yes, you’re exposed to the same attack. Switch to `pull_request` with approval gates, or move the publish step to a dedicated service account with narrow permissions.
Turn on npm provenance attestation for anything you publish. SLSA Level 3 provenance gives downstream consumers a verifiable chain from source commit to published artifact. If you maintain internal tools or client libraries, this isn’t optional anymore.
Why npm’s Trusted Publishing Wasn’t Enough
This is the uncomfortable truth.
npm built a solid trust framework. OIDC tokens. SLSA provenance. Sigstore signatures. SLSA levels. The whole stack is designed to prove that a package was built on the project’s real infrastructure.
But when the runner process itself is compromised, the OIDC token in memory is no longer your friend. It’s theirs. The signature passes every check since it came from the right machine. The machine was just doing the wrong thing.
This is the supply chain attack pattern that keeps security people awake. Not a break-in. A trusted process doing untrusted work.
The blast radius went well beyond npm. PyPI got hit in the same campaign. Mistral AI’s SDK (`mistralai==2.4.6`), UiPath, OpenSearch, Guardrails AI. Someone even swapped a Cemu emulator release on GitHub. If any of those names appear in your dependency tree, don’t assume you’re clean. Assume you’re not.
The TanStack team moved fast once they detected it. Fast doesn’t erase 518 million downloads. Go check your lockfile. I’ll be here.
Sources
– Google GTIG “Big Sleep” Report — May 2026
– OpenAI Security Advisory on the incident
– GitHub Security Lab: Preventing pwn requests in GitHub Actions
– npm Trusted Publishing documentation
– Sigstore project page
– SLSA Supply Chain Levels framework
– TanStack Security Advisory and remediation guidance
– GitHub pull_request_target documentation
– OpenAI Codex Security documentation
