The largest supply chain attack in history

Issue #422.September 9, 2025.2 Minute read.
Bytes

Today’s issue: Animation sacrilege, Fruit Rolldowns, and getting a little too forward about the size of your embeddings.

Welcome to #422.


Eyeballs logo

The Main Thing

Misty from Pokemon holding up a cross

Me installing any npm package from now on

The largest supply chain attack in history

If you decided yesterday that you wanted to be super productive by logging off social media and updating all your dependencies, I have some very bad news for you.

Early Monday morning, attackers sent a convincing 2FA-reset phishing email to a prolific OSS maintainer named Qix – and unfortunately, our guy got pwned. This enabled a massive supply chain attack with malicious patch releases for foundational npm utilities like chalk, strip-ansi, debug and color-convert, which rack up billions of combined weekly downloads.

What the malware does:

  • It’s a “crypto-clipper” that monkey-patches fetch/XMLHttpRequest, scans JSON/text for wallet addresses (ETH, BTC, SOL, etc.), then replaces those legit wallet addresses with one of the attacker’s wallets instead

  • It uses the Levenshtein Distance Algorithm to make sure that the replacement wallet looks visually similar to the original wallet, so that it’s almost impossible to catch

  • If a wallet is present, it intercepts the RPC calls and rewrites the transaction recipient so that it goes straight to the attacker

Yes, this does give us one more reason to hate crypto bros – but the scary part is that these weren’t some random crypto libraries that were affected. And it follows a similar playbook to last week’s Nx s1ngularity incident, where maintainer access gets subverted and developers get burned because of how the open source ecosystem runs on trust.

Thankfully, the attack was noticed and reported early after a few folks started noticing strange build errors like fetch is not defined. Qix owned the mistake quickly and publicly, and worked with the community and the npm security team to fix the issue. Most of the affected packages are now back to normal.

And unfortunately for Mr. Robot the Bl4ckh4t, all reports seem to indicate that they walked away with less than $100, despite having successfully perpetrated what was arguably the largest supply chain attack of all time. Couldn’t have happened to a nicer guy.

Bottom Line: This all could’ve been way worse, and we’re lucky that it was caught and remedied as quickly as it was. But unfortunately, it’s hard to see the conditions that enable attacks like these changing in a material way anytime soon. And that’s a little frightening.

Bottom Bottom Line: Never check your email, upgrade your dependencies, or leave your house.


Convex logo

Our Friends
(With Benefits)

Spongebob showing off his leg

When you build your entire backend with TypeScript

Convex is the missing half of your React app

Their all-in-one backend platform provides everything you need to build, launch, and scale a production-ready backend.

The best part? It lets you use TypeScript to write queries as code that are automatically cached and realtime, with a reactive database that’s built for AI apps.

It also gives you:

Try one of their Quickstarts – to instantly get up and running with Next.js, TanStack Start, or pretty much any other framework.


Spot the Bug logo

Spot the Bug

Sponsored by Augment Code

This article shows how you can turn their Auggie CLI into a PR review bot that can catch obvious issues automatically and make your code reviews faster and better.

function getId(user, fallback) {
  return user && user.id ?? fallback;
}

Cool Bits logo

Cool Bits

  1. Addy Osmani wrote about a history of Google Chrome for its 17th birthday. It’s really well written, but it might’ve been a little awkward if last week’s anti-trust case had gone differently.

  2. Sentry is hosting a free workshop on Building and monitoring AI agents and MCP servers that’ll go deep under the hood of MCP monitoring and show how to debug client connection issues, tool call performance, transports, and more. [sponsored]

  3. Emil Kowalski wrote about how you don’t need animations – which is kind of like the inventor of Coca-Cola saying you don’t need bubbly water, or cola flavoring… or cocaine.

  4. Apparently it’s birthday week, because GraphQL just turned 10 years old yesterday and launched a fancy new home page. They’re gonna have to share the funfetti cake we got for Chrome.

  5. Legend List just launched v2.0 of their super-fast React Native list library with more accuracy, more speed, sticky headers, and more.

  6. Nolan Lawson wrote an article to answer the age-old question, Why do browsers throttle JavaScript timers? I don’t know, but I’m gonna go ahead and say that it’s IE’s fault.

  7. JetBrains is hosting JavaScript Day 2025 online on October 2nd for free. Tune in for a full day of live Q&A’s and talks from experts like Ryan Carniato, Lydia Hallie, Kent C. Dodds, Victor Savkin, and lots more. [sponsored]

  8. Vicki Boykis wrote an article called, How big are our embeddings now and why? Sorry Vicki, but my mother taught me not to answer those questions until after the third date.

  9. Christoph Nakazawa (creator of Jest and former React Native Lead) gave this talk on building scalable applications at last week’s React Universe Conf.

  10. kazupon wrote about how his team at Plaid achieved 87x faster server-side action builds by migrating from Rollup to Rolldown. That might be true, but you’ve never heard about an 8-year-old kid go crazy after giving themselves a face tattoo with a Fruit Rolldown.


Spot the Bug logo

Spot the Bug: Solution

Sponsored by Augment Code

You can’t mix the nullish coalescing operator ?? with && (or ||) in the same expression without parentheses.

function getId(user, fallback) {
  return (user && user.id) ?? fallback;
}

or even better, just use optional chaining:

function getId(user, fallback) {
  return user?.id ?? fallback;
}