arrow_backBack to Blog
securitynpmsupply chainJavaScriptengineering

TanStack npm Under Attack: Mini Shai-Hulud Worm Compromised 160+ Packages, Affected OpenAI

personLab Desenvolvimento
schedule5 min

On May 11, 2026, the JavaScript ecosystem suffered one of the most sophisticated supply chain attacks ever seen on npm. TanStack — maintainer of widely used libraries like React Query and TanStack Table — was targeted in an attack that compromised 42 packages across 84 malicious versions, indirectly affecting hundreds of downstream projects, including OpenAI.

How the attack worked

The incident, documented in a detailed post-mortem by founder Tanner Linsley, combined three vulnerabilities:

  1. Pull Request Target (Pwn Request): The attacker opened a PR against the TanStack/router repository using a newly created account. Since pull_request_target workflows have unrestricted access to base repository secrets, no first-time contributor approval was needed.

  2. Cache Poisoning: Inside the PR, a malicious commit (vite_setup.mjs, ~30,000 lines of obfuscated JS) was executed during benchmarking, poisoning the GitHub Actions cache with a key matching the main branch (refs/heads/main).

  3. OIDC Token Extraction: When the release ran days later, the poisoned cache was restored. The malware extracted the OIDC token from the GitHub Actions runner runtime and used it to publish packages directly to the npm registry, even with failing tests.

No npm tokens were stolen. The publish mechanism was not compromised. The attacker used the workflow's own OIDC token, which has id-token: write permission, to authenticate directly to npm, explained Tanner Linsley in the post-mortem.

The Mini Shai-Hulud worm

The ~2.3 MB payload (router_init.js) was a self-propagating worm that:

  • Harvested credentials from AWS IMDS, GCP metadata, Kubernetes tokens, Vault, GitHub, SSH keys, and .npmrc
  • Exfiltrated via the Session/Oxen Messenger upload network (end-to-end encrypted, no attacker-controlled C2)
  • Self-propagated: enumerated other packages the victim maintained and republished them with the same malicious injection

Detection and response

  • 19:20-19:26 UTC — Malicious packages published
  • 19:46 UTC — External researcher ashishkurmi (StepSecurity) opened issue reporting the attack
  • ~20:00 UTC — TanStack team began incident response
  • 20:19 UTC — First package deprecated
  • All affected versions were deprecated and removed by npm

Impact: The worm spread beyond TanStack. As the payload enumerated and republished packages from victims, hundreds of packages in the chain were compromised, reaching even projects like OpenAI.

Lessons learned

  1. pull_request_target is inherently risky — audit workflows that use it
  2. Cache poisoning attacks in CI/CD are underestimated and extremely hard to detect
  3. Blind trust in OIDC trusted publishers does not eliminate risk if the runtime runner is compromised
  4. The JavaScript supply chain remains one of the most critical attack vectors

Official post-mortem: TanStack Blog