← SurfacedDrop no. 13Tech news drama5min read

The TanStack npm Worm That Minted Its Own Credentials

The story behind the drop.

A six-minute publish window on May 11, 2026 turned TanStack's CI pipeline into a self-propagating npm worm that needed no human password.

Published

UTC

Reading time

5 min

~210 wpm

Word count

1,148

plain English

Category

Tech news drama

tech-news-drama

For six minutes on May 11, 2026, a worm running inside TanStack's own GitHub Actions pipeline published its way into the dependency trees of millions of JavaScript projects without stealing a single human password.

A six-minute publish window

Between 19:20 and 19:26 UTC on May 11, 2026, an attacker pushed 84 malicious package versions across 42 @tanstack/* libraries on npm. The window is the part that matters. @tanstack/react-router, one of the poisoned libraries, is downloaded over 12 million times per week, which means a developer running a fresh install anywhere in the world during those six minutes could have pulled the worm directly into a production environment. There was no slow burn, no staged rollout, no time to notice. The first wave landed inside the time it takes to brew coffee.

The compromise was the second wave of a self-propagating campaign that researchers track as Mini Shai-Hulud, signed inside its infrastructure with the tag "With Love, TeamPCP." The broader May 11 wave ultimately touched 139 distinct package names and more than 340 individual versions, including UiPath, DraftLab, TaskFlow, Tolka, and @mistralai/mistralai bundles. TanStack was the loudest brand in the wave, but it was not alone.

Two GitHub accounts, zblgg (user ID 127806521) and voicproducoes (user ID 269549300), have been linked to the activity by Socket researchers. The voicproducoes account had previously published a public repository titled "A Mini Shai-Hulud has Appeared," which reads less like operational security and more like a calling card. The poisoned commit inside TanStack's repository was authored under the fabricated email claude@users.noreply.github.com, designed to look like an AI bot signature and unrelated to Anthropic in any way.

Three weaknesses in one repository

The intrusion never touched a maintainer's laptop. It chained three weaknesses inside TanStack's own GitHub Actions setup, in sequence.

The first was a pull_request_target misconfiguration in bundle-size.yml, a pattern security researchers call a Pwn Request. The directive allows workflows from forked pull requests to run with write-level access to the parent repository's secrets, which is occasionally useful and frequently dangerous. The second was GitHub Actions cache poisoning across the fork-to-base trust boundary, anchored by a 1.1 GB pnpm cache stored under the key Linux-pnpm-store-6f9233a. That cache was the staging payload. The third was an OIDC token extraction from the live runner's process memory using /proc/<pid>/mem, which let the worm read out the short-lived token GitHub issues to authenticate publishes.

With the OIDC token in hand, the worm minted its own publish-capable npm credentials. From there, it behaved less like an exploit and more like a process. It enumerated the victim maintainer's other packages on the npm registry and republished trojanised versions of each one, which is how 42 libraries flipped in six minutes. One of the stolen npm tokens was labelled inside the registry with the warning "IfYouRevokeThisTokenItWillWipeTheComputerOfTheOwner," a deliberate intimidation bluff aimed at slowing down incident responders.

What router_init.js did on install

Inside each malicious tarball was a 2.3 MB obfuscated JavaScript file named router_init.js that ran on install. The file is the actual weapon. It harvested AWS IMDS and Secrets Manager values, GCP metadata, Kubernetes service-account tokens, HashiCorp Vault tokens, the user's ~/.npmrc, GitHub tokens, and private SSH keys. If a CI runner had a credential available to it, the payload tried to take it.

Stolen secrets left the host through endpoints on the encrypted Session messenger network, including filev2.getsession.org and seed1.getsession.org. The choice is clever in the way that defensive teams dislike: exfiltration traffic looked like routine end-to-end encrypted chat, which is hard to flag without context. A separate command-and-control domain, api.masscan.cloud, fetched the second-stage payload from litter.catbox.moe/h8nc9u.js.

What made the campaign distinctive, beyond the spread, was the provenance. StepSecurity called this "the first documented npm worm that produces validly-attested malicious packages," meaning the poisoned versions carried correct SLSA provenance metadata pointing back to TanStack's real CI pipeline. The cryptographic story was perfectly clean. The artefacts came from the right place, signed by the right machinery, on the right schedule. They simply happened to be malware. As StepSecurity put it in their research blog, "SLSA provenance confirms which pipeline produced the artifact, not whether the pipeline was behaving as intended." That is the sentence the rest of the supply-chain security industry now has to internalise.

Detection inside six minutes, deprecation inside two hours

The response told a parallel story about what is and is not working in 2026. Socket's AI scanner flagged every malicious TanStack version within six minutes of publication, before most CI systems had even completed their nightly builds. Ashish Kurmi, lead researcher at StepSecurity, filed issue #7383 on TanStack/router roughly 20 minutes after the publish window closed, around 19:50 UTC. "The self-propagating malware, which spreads by stealing CI/CD secrets, compromised several @tanstack npm packages," Kurmi wrote.

The maintainers moved quickly from there. TanStack revoked the team's push permissions at 20:10 UTC, engaged npm security at 20:30 UTC, and had all 84 malicious versions deprecated by roughly 21:00 UTC. The cleanup required direct intervention because npm's policy does not allow unpublishing a package if any other package depends on it. The tarballs had to be removed server-side rather than through the normal CLI flow, which is the registry's equivalent of breaking glass. Six TanStack package families were confirmed clean in the postmortem: @tanstack/query, @tanstack/table, @tanstack/form, @tanstack/virtual, @tanstack/store, and @tanstack/start.

What survives when provenance is not enough

The remediation guidance is unambiguous and worth quoting directly. "Anyone who installed an affected version on May 11, 2026, should rotate AWS, GCP, Kubernetes, Vault, GitHub, npm, and SSH credentials," the TanStack postmortem states. Seven different secret stores, all touched by a single install hook in a 2.3 MB script. The incident is tracked publicly as GitHub Security Advisory GHSA-g7cv-rxg3-hmpx and CVE-2026-45321.

The deeper lesson is harder to action. Static trust systems worked exactly as designed. The packages were signed, the provenance pointed to the right pipeline, the registry accepted the publishes. The attacker did not need to steal a single human npm credential because the worm minted its own publish-capable tokens by reading the live OIDC token out of the GitHub Actions runner. Identity, in the cryptographic sense, was never the question. Behaviour was. The attack moved the contested ground from "who signed this" to "what was that pipeline actually doing when it signed it," and the industry's existing controls have very little to say about the second question.

For a while, "look at the provenance" was the answer to supply-chain anxiety. After May 11, 2026, it is one input among several.

Sources