TanStack's npm Meltdown: Mini Shai-Hulud Worm Hits 42 Packages
May 11, 2026. 19:20 UTC. While most of us were debating whether to use use or queryClient for the 47th time, TanStack’s release pipeline quietly shipped 84 malicious versions across 42 @tanstack/* packages.
Yes, the same TanStack Router family that powers half the modern React (and Solid/Vue/Svelte) apps just became a self-spreading credential-stealing worm nicknamed Mini Shai-Hulud (because nothing says “fun supply-chain attack” like a baby sandworm from Dune).
In six glorious minutes the attacker published under TanStack’s own trusted OIDC identity. No stolen npm token. No compromised maintainer account. Just pure GitHub Actions dark magic.
If you ran npm install, pnpm install, or yarn install on any affected package that day… your machine is now a potential credential farm. Welcome to the club.
What Actually Happened? (The Technical Horror Story)
TanStack’s own postmortem is a masterpiece of transparency (go read it), but here’s the distilled, slightly-less-corporate version:
-
The Pwn Request (pull_request_target magic)
Attacker forksTanStack/router, renames it to something boring to hide in fork lists, and opens a PR titled “WIP: simplify history build”.
TanStack’sbundle-size.ymlworkflow usedon: pull_request_target(the classic “trust me bro” trigger). It happily checked out the merge commit of the fork and ran attacker code on the base repo’s runner. -
Cache Poisoning Party
The malicious PR dropped a sneakyvite_setup.mjsthat wrote a poisonedpnpm-storeentry using the exact cache key the realrelease.ymlworkflow would later restore (Linux-pnpm-store-6f9233a5…).
GitHub Actions cache doesn’t care about your fork trust boundaries. Poisoned cache saved. Boom. -
OIDC Token Heist from Runner Memory
Later that evening a legit maintainer PR merges →release.ymlruns.
Poisoned cache restores → malware wakes up, finds the GitHub Actions worker process via/proc/*/cmdline, dumps its memory (/proc/<pid>/mem), and extracts the freshly minted OIDC token (because the workflow hadid-token: write).
Then it POSTs straight toregistry.npmjs.org— bypassing the actual “Publish Packages” step entirely.
Result? 42 packages (mostly router family, devtools, adapters, history, etc.) got two malicious versions each. @tanstack/query*, @tanstack/table* and friends stayed clean. Small mercies.
The malware itself? A 2.3 MB obfuscated router_init.js (hidden in the tarball, not even listed in files). It runs at install time via a cheeky optionalDependencies hack pointing to an orphan commit in a fork. The prepare script fires, does its thing, then politely exit 1 so the install “succeeds” anyway.
What the Worm Actually Did (And Why You Should Panic)
Once installed it went full supply-chain gremlin:
- Scanned for AWS creds, GCP metadata, K8s service accounts, Vault tokens,
~/.npmrc, GitHub tokens, SSH keys — you name it. - Exfiltrated everything over the Session/Oxen messenger network (E2E encrypted, no obvious C2 server for defenders to block).
- Self-propagated by querying npm for other packages the victim maintained and republishing them with the same payload.
- Left persistence goodies in
~/.vscodeand VS Code settings for good measure. - Bonus dead-man’s switch: if tokens get revoked it could nuke your home directory (because why not go full villain?).
518+ million cumulative downloads across the broader campaign. Oof.
The Humour in the Chaos (Because Otherwise We’d Cry)
My favourite part? The attacker didn’t even need to steal long-lived secrets. They just borrowed the pipeline’s own lunch money while it was looking the other way.
It’s like watching someone pick the lock on your front door using the spare key you left under the welcome mat… that you yourself programmed the house to hand out.
Also: “Single pane of glass? More like single point of worm.”
And yes, the irony of a routing library getting pwned by a PR is chef’s kiss.
Lessons for Us Mere Mortals (CI/CD Takeaways)
- Audit your
pull_request_targetworkflows yesterday — addrepository_ownerguards, require approval for first-time contributors, or just stop using it for anything that touches cache or secrets. - Cache is not sacred — isolate caches per workflow, per branch, or use immutable cache keys. Consider disabling cache for release jobs entirely if you’re feeling paranoid.
- OIDC tokens are powerful but lazy — they sit in memory. Memory scraping is a real thing now. Rotate aggressively and monitor for anomalous publishes.
- Sign your releases properly — provenance is nice, but when the attacker publishes through your pipeline it’s still trusted. Add package cooldowns, manual approval gates for major versions, or external signing.
- Treat
npm installas untrusted —ignore-scriptsin CI, lockfile audits, SBOMs, and never runnpm installon production runners without verification. - Monitor your own publishes — TanStack had zero internal alerting on sudden npm version spikes. Add it. Now.
TanStack already hardened everything: purged caches, restructured workflows, pinned actions to SHAs, revoked permissions, and deprecated the bad versions.
Final Thought
Supply-chain attacks like this are the new normal. We keep building bigger, shinier CI/CD castles while attackers just walk in through the side door we left open for “convenience”.
Mini Shai-Hulud is a reminder that even the best open-source teams (shoutout to Tanner and the crew for the transparent postmortem) can get caught by chained “known” vulnerabilities.
So go audit your workflows, rotate those creds, and maybe keep a copy of Dune nearby — because the worms are coming.
Until next time — may your caches stay clean, your PRs stay boring, and your npm install stay drama-free.
P.S. Full TanStack postmortem: tanstack.com/blog/npm-supply-chain-compromise-postmortem
GitHub Advisory: GHSA-g7cv-rxg3-hmpx
Stay safe out there, folks. And maybe pin your TanStack versions to pre-May 11 for a hot minute. 😏
// RELATED_ARCHIVES
> Mar 2026 · 7 min read
NVIDIA NemoClaw: Taming Rogue AI Agents for Enterprise
OpenClaw agents were fun until they started deleting prod databases. NVIDIA NemoClaw adds the guardrails enterprises need – one command to safe, always-on AI assistants.
> Dec 2025 · 7 min read
React's React2Shell Hack: When Your UI Library Gets a Backdoor
A critical RCE bug (CVE-2025-55182) in React Server Components let hackers shell into millions of servers. Patch now, or your app's serving more than just JSX.
> Dec 2025 · 5 min read
React's RCE Wake-Up Call - Patch Before Hackers Say 'Hello World'
CVE-2025-55182 hits React Server Components hard with unauthenticated RCE. A quick dive into the deserialization drama, who's affected, and how to fix it without pulling your hair out.