TanStack Attack

Issue #486.May 13, 2026.2 Minute read.
Bytes

Today’s issue: Great libraries steal, brilliant rodents build terminal emulators, and your local PBS station helps you write CSS.

Welcome to #486.


Eyeballs logo

The Main Thing

A woman holding a little hand that says help on it

Me after revoking my GitHub tokens without reading the postmortem first

TanStack Attack

Yesterday, an attacker published 84 malicious versions across 42 @tanstack/* packages that were live for ~20 minutes before external researcher ashishkurmi caught it.

The good news is that it was discovered quickly, so packages were deprecated and tarballs pulled. The bad news is that if you ran npm install yesterday, your machine may be cooked.

How it worked: The attack worked by chaining three vulnerabilities together. A malicious PR exploited pull_request_target in GitHub Actions to poison the shared pnpm cache with a custom payload.

So the next time a legitimate release ran, it restored that poisoned cache, and the attacker’s code extracted an OIDC token directly from runner memory to publish to npm without ever touching a stored credential. To npm, the poisoned version looked 100% legitimate.

And once installed, the payload got pretty nasty:

  • Credential harvesting — AWS, GCP, Kubernetes, Vault, GitHub tokens, SSH keys, ~/.npmrc. Everything reachable from the install host.

  • Self-propagating worm — Queries the npm registry for other packages the victim maintains and reinfects those too.

  • Dead man’s switch~/.local/bin/gh-token-monitor.sh installs as a systemd service (Linux) or LaunchAgent (macOS) and polls api.github.com/user with the stolen token every 60s. If the user revokes the token, it runs rm -rf ~/. Revoking is what pulls the trigger, so do not just go rotating credentials before you read the full warning.

What to do:

  • Carefully rotate credentials if you installed any @tanstack/* package on May 11th

  • Set a minimum release age in your package manager. A 7-day hold would have blocked most known supply chain attacks from the past 8 years

  • Upgrade to pnpm 11, which has supply chain attack mitigations baked in

Bottom Line: TanStack is one of the most respected and well-maintained OSS orgs we have. So if they can get hit this cleanly, maybe it’s finally time for the industry to move on from npm for good.

We can dream.


QA Wolf logo

Our Friends
(With Benefits)

A monkey lying in bed on a computer

When testing the code takes longer than writing the code

The testing platform built for AI software development

When testing can’t keep up with AI, your team’s PRs pile up, releases get stuck in QA, and you ship a lot more slop to production.

QA Wolf built a testing platform for agentic SDLC, so your team can ship fast and fearlessly:

  • Mapping AI autonomously maps your app’s workflows
  • Automation AI generates deterministic, code-based tests for web, iOS, and Android
  • 100% parallel runs return results in minutes

Get a personalized demo for your team – and see why one Salesloft engineer said, “I’ve never seen anything like QA Wolf’s parallel run infrastructure.”


Pop Quiz logo

Pop Quiz

Sponsored by Clerk

The new Clerk CLI gives you a single command, clerk init that detects your framework, scaffolds Clerk into your project, and wires up auth end to end with middleware, providers, auth pages, and more.

What gets logged?

function Dog(name) {
  this.name = name
  this.speak = () => 'Woof Woof'
}

Dog.prototype.speak = function() {
  return 'Ruff Ruff'
}

const dog = new Dog('Leo')
console.log(dog.speak())

Cool Bits logo

Cool Bits

  1. Tailwind CSS v4.3 comes with new scrollbar utilities, new zoom utilities and lots of other little stuff that’s only possible thanks to contributions to your local PBS station from viewers like you.

  2. Jad Joubran wrote about 9 times the web platform was influenced by libraries. Like how my Pre-Calc final answers were influenced by my friend Jon Lee.

  3. Greptile in Action is a fun collection of bugs that Greptile caught in some of the most popular open source repos like PyTorch, CUDA, and OpenClaw. And it links to each PR in GitHub, so you can dive deeper. [sponsored]

  4. Waku 1.0 beta comes with version skew handling, a Vite 8 upgrade with Rolldown, and new compatibility updates for the minimal RSC framework.

  5. Expo 56 beta comes with 50% faster iOS builds, stable Expo UI, and stable iOS widgets. But by the time your App Store review gets approved, we’ll be on Expo 87.

  6. Blacksmith is a drop-in replacement for GitHub runners that costs 60% less and is 2x faster because it runs on bare metal gaming CPUs. And all your actions are fully observable. [sponsored]

  7. Sylvie wrote up how they discovered and disclosed the React2Shell RCE in React Server Components.

  8. Cyrus made the case for why local AI should become the norm.

  9. 16 ways to make a small language model think bigger breaks down fundamental strategies you can use to make smaller models better at multi-step reasoning, without increasing their size. [sponsored]

  10. Jeff Kaufman explained how AI is breaking two vulnerability cultures.

  11. Aral Roca wrote about The O(n^2) bug that looked like clean code. If I had a dollar for every time I’ve thought that.

  12. Ratty is a terminal emulator with inline 3D graphics and a spinning rat cursor built by Orhun Parmaksız, while under the influence of the small rodent living under his hat and controlling his hands.


Pop Quiz logo

Pop Quiz: Answer

Sponsored by Clerk

What gets logged?

function Dog(name) {
  this.name = name
  this.speak = () => 'Woof Woof'
}

Dog.prototype.speak = function() {
  return 'Ruff Ruff'
}

const dog = new Dog('Leo')

Woof Woof gets logged.

Before JavaScript delegates the lookup of the property to the Constructor’s prototype, it first checks to see if the property exists on the object being returned from the Constructor. In this case, it does so it calls it.