Original title: npm supply chain compromise postmortem
Article
A single campaign compromised the TanStack release pipeline on 2026-05-11 by chaining a forged fork PR, cache poisoning, and runtime token extraction into a publish path. The attacker used pull_request_target jobs to execute fork-controlled code, polluted the pnpm cache, then relied on a later release workflow on main to restore that cache and run a prepare-time payload during install. Two versions of 84 packages across 42 @tanstack/* entries were published in a 20-minute window, while the release workflow’s intended publish step did not execute because the normal job path failed. The payload was distributed via optionalDependencies entries pointing to a forked router commit and executed through npm lifecycle scripts after install, triggering host-side actions and a 2.3 MB obfuscated script. No direct theft of npm tokens was confirmed, but the maintainers stated that any machine running installs of affected versions on that date should assume compromise and rotate AWS, GCP, Kubernetes, Vault, GitHub, npm, and SSH credentials. External researchers discovered the activity quickly, the tarballs were pulled, and all affected versions were deprecated with public advisory coordination. A tracking issue confirmed the full scope, and emergency response included cache purges, permission tightening, workflow guards, and action pinning. The incident is presented as a three-part chain where each link was insufficient alone: fork merge execution, cache trust crossing, and OIDC publish privilege on a CI runner. The release relied on known CI trust boundaries rather than introducing a separate gate for registry publishing, and the post concludes that the pipeline was the failure point, not one single software bug.
Commenters emphasized that trusted publishing alone is not a secure boundary because a compromised CI workflow or repo admin can still mint publish tokens and push packages, so they called for staged, human-assisted registry promotion with an external second factor. They also noted indicators beyond the initial chain, including a token watchdog that appears to monitor and delete local home data if revocation is detected, plus a related compromise claim in @mistralai/mistralai. Multiple users argued lifecycle scripts and package freshness controls are critical defenses, recommending ignore-scripts and minimum release-age/cooldown settings in npm, pnpm, bun, or uv to reduce exposure to newly published, unvetted artifacts. Several participants traced lineage to prior attacks and public research, framing this as recombined but recognizable tradecraft in GitHub Actions and supply-chain abuse. Some criticism targeted platform-level risk in GitHub’s pull_request_target behavior and cache sharing across trust boundaries, while others criticized npm’s detection and retention posture. There was broad concern that ecosystem design encourages rapid transitive dependency dependency risk, though many acknowledged strong detection and cleanup response reduced blast radius. Sentiment was mixed between technical recommendations, platform blame, and long-running frustration with JavaScript ecosystem defaults.