84 Malicious TanStack Packages Hit npm Via GitHub Actions Exploit Chain

5 min read 1 source breaking
├── "The attack's sophistication lies in chaining known vulnerabilities, not in novel exploits"
│  ├── TanStack team (TanStack Blog) → read

The postmortem details how the attacker combined three individually well-documented vulnerabilities — pull_request_target Pwn Requests (known since 2020), GitHub Actions cache poisoning across fork boundaries, and OIDC token extraction from runner memory. The team emphasizes that none of these were zero-days, yet chaining them proved devastatingly effective against npm's Trusted Publishing mechanism.

│  └── @varunsharma07 (Hacker News, 954 pts)

Flagged the incident and highlighted the exploit chain's breadth, noting the same worm-like propagation hit @mistralai/mistralai on npm. Their framing emphasizes the systemic nature of the attack rather than any single novel technique.

├── "GitHub Actions' trust model between forks and base repositories is fundamentally broken"
│  └── TanStack team (TanStack Blog) → read

The postmortem implicitly indicts GitHub's architecture by detailing how shared cache storage between forks and base repositories enabled the pivotal step of the attack. The pull_request_target event granting write access in PR context has been a documented footgun for six years, yet remains a default capability that maintainers must actively defend against.

├── "The persistence mechanism makes remediation far harder than just reverting packages"
│  └── TanStack team (TanStack Blog) → read

The postmortem specifically calls out the dead-man's switch payload — a systemd user service on Linux and LaunchAgent on macOS that continuously polls GitHub's API with stolen tokens. They flag this as a 'critical detail for remediation,' signaling that simply removing the malicious package versions is insufficient; affected developers must also audit their systems for persistent backdoors.

└── "npm's Trusted Publishing via OIDC creates a dangerous new attack surface"
  └── TanStack team (TanStack Blog) → read

The postmortem reveals that OIDC tokens extracted from GitHub Actions runner memory were sufficient to publish 84 malicious versions across 42 packages. This demonstrates that Trusted Publishing — designed to eliminate long-lived npm tokens — introduces its own risk by making ephemeral CI credentials a high-value target that can be exploited within the same runner environment.

What Happened

On May 11, 2026, an attacker executed a multi-stage supply-chain attack against TanStack — the widely-used open-source project behind TanStack Query, TanStack Router, TanStack Table, and dozens of other packages that collectively see millions of weekly npm downloads. The attacker chained three distinct vulnerabilities — a pull_request_target Pwn Request, GitHub Actions cache poisoning across the fork-to-base trust boundary, and OIDC token extraction from runner memory — to publish 84 malicious package versions across 42 @tanstack/* packages on npm.

The attack vector was sophisticated but not novel in its individual components. The `pull_request_target` event in GitHub Actions has been a known footgun since 2020: it runs workflow code from the *base* branch but in the context of the *pull request*, which means a forked PR can trigger workflows with write access to the target repository. What made this attack notable was the chaining. The attacker poisoned the GitHub Actions cache — exploiting the shared object storage between forks and base repositories — to inject code that would execute during legitimate CI runs. From there, they extracted OIDC tokens from runner memory, which gave them the ability to publish packages via npm's Trusted Publishing mechanism.

The compromise also extended beyond TanStack. As community member varunsharma07 flagged, the @mistralai/mistralai npm package was compromised as part of the same worm-like propagation, with the malicious version eventually pulled from the registry.

The Payload: A Dead-Man's Switch

The malicious packages didn't just exfiltrate data — they established persistence. On installation, the payload dropped a dead-man's switch at `~/.local/bin/gh-token-monitor.sh` as a systemd user service on Linux and a LaunchAgent (`com.user.gh-token-monitor`) on macOS. This service polls `api.github.com/user` with the stolen GitHub token at regular intervals.

This is a critical detail for remediation. As HN commenter cube00 warned: simply revoking tokens isn't sufficient if the monitoring service is already installed. The persistence mechanism means the attacker can detect when their stolen credentials stop working and potentially escalate before you've finished cleaning up. Any remediation plan needs to include checking for and removing these services *before* revoking tokens — or at minimum, doing both simultaneously.

Why npm Made It Worse

The TanStack team's postmortem reveals a painful operational reality: npm's "no unpublish if dependents exist" policy meant the team couldn't remove the malicious packages themselves. They had to file a request with npm's security team and wait for server-side tarball removal. During those hours of delay, every `npm install` that resolved to an affected version was pulling down the compromised code.

This is a policy designed to prevent the left-pad scenario — where unpublishing a popular package breaks half the internet. But as commenter ezekg pointed out, it creates a perverse incentive structure during active supply-chain compromises: the more popular a package is (and thus the more critical it is to remove a malicious version), the harder it is to remove. The npm team has the ability to act, but the human-in-the-loop delay during an active incident is measured in hours, not minutes.

For context, pnpm users had a partial mitigation here. As chrisweekly noted, pnpm's stricter handling of postinstall scripts and its content-addressable store model reduce (but don't eliminate) the attack surface. The broader point stands: the npm ecosystem's trust model has a structural gap between "package published" and "package verified safe."

The Trusted Publishing Paradox

Perhaps the most uncomfortable takeaway is what this attack means for OIDC-based Trusted Publishing — the mechanism that was supposed to make npm publishing safer by eliminating long-lived tokens. Trusted Publishing worked exactly as designed, and the attacker used it to publish malicious packages. As jonchurch_ observed, TP is not meant to guarantee against an attacker who is already inside your CI pipeline. It prevents stolen npm tokens from being used *outside* CI; it says nothing about the integrity of what happens *inside* CI.

This isn't a failure of Trusted Publishing — it's a failure to understand its threat model. TP solves the "developer laptop compromised, npm token stolen" scenario. It does not solve the "CI pipeline compromised" scenario. The TanStack attack lived entirely within the CI trust boundary, which means the OIDC tokens it extracted were legitimate, the publish operations were authorized, and npm had no signal that anything was wrong.

The implication for maintainers is stark: Trusted Publishing is a necessary but insufficient security measure. You also need to harden your CI pipeline itself — which means auditing `pull_request_target` usage, understanding cache trust boundaries, limiting OIDC token permissions, and treating your GitHub Actions configuration as a security-critical attack surface.

What This Means for Your Stack

Immediate actions: Check your lockfiles. If any `@tanstack/*` dependency shows a version published on May 11, 2026, pin to the last known-good version from before that date. Search your systems for `gh-token-monitor.sh` (Linux) or the `com.user.gh-token-monitor` LaunchAgent (macOS). If found, remove the persistence mechanism and rotate all GitHub tokens, npm tokens, and any other credentials accessible from that machine.

CI hardening: Audit every workflow that uses `pull_request_target` — if you don't understand exactly why it's there and what permissions it grants, replace it with `pull_request`. Review your GitHub Actions cache usage and consider whether fork PRs should be able to influence cache contents. If you use OIDC-based publishing, scope the tokens as narrowly as possible and add manual approval gates for publish steps.

Dependency management: This is the third major npm supply-chain incident in 18 months, and the attack sophistication is increasing. If you're not already using a lockfile, start. If you're not pinning exact versions in CI, start. If you're not running `npm audit` in CI, start. Consider tools like Socket.dev or Snyk that analyze package behavior rather than just known vulnerabilities. And if you're still running `npm install` with postinstall scripts enabled by default, evaluate whether `--ignore-scripts` with explicit allowlists is feasible for your workflow.

Looking Ahead

The TanStack compromise marks an inflection point in supply-chain attack sophistication. The individual techniques — Pwn Requests, cache poisoning, OIDC extraction — have all been documented in security research. What's new is seeing them chained together against a high-profile target with surgical precision. GitHub's shared object storage model for forks, npm's unpublish restrictions, and the gap between Trusted Publishing's promise and its actual threat model all contributed to the blast radius. Expect GitHub to face pressure to rearchitect the fork trust boundary, npm to revisit emergency unpublish policies, and the ecosystem to reckon with the fact that CI pipelines are now the primary attack surface for package registries — not developer laptops, not stolen tokens, but the automation we built to make publishing safer.

Hacker News 1073 pts 451 comments

Postmortem: TanStack npm supply-chain compromise

<a href="https:&#x2F;&#x2F;github.com&#x2F;TanStack&#x2F;router&#x2F;issues&#x2F;7383" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;TanStack&#x2F;router&#x2F;issues&#x2F;7383</a>

→ read on Hacker News
cube00 · Hacker News

Please be careful when revoking tokens. It looks like the payload installs a dead-man&#x27;s switch at ~&#x2F;.local&#x2F;bin&#x2F;gh-token-monitor.sh as a systemd user service (Linux) &#x2F; LaunchAgent com.user.gh-token-monitor(macOS). It polls api.github.com&#x2F;user with the stolen token every

Ciantic · Hacker News

What I want to focus on is mental model of your CI pipeline, and problem with too much YAML, consider this quote:&gt; Cache scope is per-repo, shared across pull_request_target runs (which use the base repo&#x27;s cache scope) and pushes to main. A PR running in the base repo&#x27;s cache scope can

jonchurch_ · Hacker News

It is unfortunate, but this is evidence (IMO) that Trusted Publishing is still ~~not secure~~ not enough by itself to securely publish from CI, as an attacker inside your CI pipeline or with stolen repo admin creds can easily publish. This isnt new information, TP is not meant to guarantee against t

chrisweekly · Hacker News

Postinstall scripts are deadly. Everyone should be using pnpm.Crazy that an &quot;orphan&quot; commit pushed to a FORK(!) could trigger this (in npm clients). IMO GitHub deserves much of the blame here. A malicious fork&#x27;s commits are reachable via GitHub&#x27;s shared object storage at a URI in

varunsharma07 · Hacker News

@mistralai&#x2F;mistralai npm package was also compromised as part of this worm https:&#x2F;&#x2F;github.com&#x2F;mistralai&#x2F;client-ts&#x2F;issues&#x2F;217It has been pulled from the npm registry now.

// share this

// get daily digest

Top 10 dev stories every morning at 8am UTC. AI-curated. Retro terminal HTML email.