
Socket: TanStack npm Packages Compromised
Socket's Threat Research team found 84 compromised @tanstack npm package artifacts (including @tanstack/react-router, 12M+ weekly downloads) injected with an obfuscated router_init.js credential-stealing payload targeting GitHub Actions CI secrets and OIDC tokens. The attack chained a pull_request_target "Pwn Request" pattern, GitHub Actions cache poisoning across the fork-to-base trust boundary, and runtime OIDC token extraction, allowing attacker publishes via TanStack's legitimate trusted-publisher OIDC binding without stealing npm tokens. Socket ties it to the ongoing Mini Shai-Hulud campaign, attributed to a likely-compromised GitHub account, and provides hashes, IOCs (filev2.getsession[.]org), and hardening/remediation steps.
What it is
84 compromised artifacts in the @tanstack npm namespace carrying a credential stealer aimed at CI systems (GitHub Actions). The malicious versions add a ~2.3 MB router_init.js and an optionalDependencies entry pointing at a git commit that runs code on install. Socket ties it to the Mini Shai-Hulud campaign; the malicious commit was authored by GitHub account voicproducoes, whose repos include one named "A Mini Shai-Hulud has Appeared" — signaling account takeover.
How it works
Two payload paths beyond the router_init.js stealer. The tampered package.json adds:
"optionalDependencies": {
"@tanstack/setup": "github:tanstack/router#79ac49eedf774dd4b0cfa308722bc463cfe5885c"
}That commit is a parentless root commit introducing only a package.json and tanstack_runner.js. Its package.json registers a prepare hook running bun run tanstack_runner.js && exit 1 — and npm runs lifecycle hooks automatically for git dependencies, so it executes on any workstation or CI installing it. The publish itself was authenticated via TanStack's OIDC trusted-publisher binding after attacker code ran in the workflow's test/cleanup phase; no npm tokens were stolen.
Preconditions / Affected
Any system that installed an affected @tanstack/* version — including transitive consumers, given @tanstack/react-router's 12M+ weekly downloads. CI runners with GitHub Actions secrets/OIDC are the primary target.
What to do
Triage — hash-match every router_init.js in your tree against the known-bad:
shasum -a 256 (all router_init.js files)
ab4fcadaec49c03278063dd269ea5eef82d24f2124a8e15d7b90f2fa8601266cRotate secrets on any affected system in priority order: npm tokens, GitHub PATs/OIDC trusts, AWS credentials (static + instance roles), Vault tokens, Kubernetes SA tokens. Revoke OIDC federation grants for affected repos and re-establish only after confirming the publishing workflow is clean.
Audit .claude/ and .vscode/ in home directories and project roots; remove router_runtime.js, setup.mjs, and unfamiliar settings.json hooks or tasks.json entries. Find suspect commits:
git log --all --author=claude@users.noreply.github.com— revert/force-push any not made through the legitimate Claude Code GitHub App.
Block egress to filev2.getsession[.]org; because Session's node IPs are distributed, DNS-block .getsession.org rather than IP rules. Set permissions: id-token: none in workflows that don't publish, and scope id-token: write to only the publishing job. Enforce pinned integrity fields in lockfiles so any hash mismatch blocks CI.
Caveats
Do not treat Sigstore provenance badges as a trust signal: the implant shows that an attacker executing inside GitHub Actions can generate valid Sigstore attestations for malicious packages. Payload detail is what Socket observed; TanStack's chain (pull_request_target "Pwn Request" → cache poisoning across the fork/base boundary → runtime OIDC extraction) comes from TanStack's own postmortem.
Organisations named here
- commit 79ac49eedf774dd4b0cfa308722bc463cfe5885c
- filev2.getsession[.]org
- Pwn Request pattern
- voicproducoes
Technologies named here
- npm
- GitHub Actions
- tanstack
- OIDC
- Sigstore
- Bun
Threat actors named here
- Mini Shai-Hulud campaign
Related in Supply Chain


