The supply chain is people

· security, supply-chain, open-source, npm, opinion

At 9:00 UTC on August 4, somebody got into a maintainer's GitHub account. By the end of the day a credential stealer was living in more than 400 npm packages, including keyv and cacheable-request, which sit underneath a very large amount of everything.

The payload went after cloud credentials, infrastructure secrets, developer credentials, cryptocurrency wallets, and AI configuration files. It pulled command-and-control domains out of an Ethereum smart contract, which is a genuinely novel way to keep your infrastructure from being taken down. It carried a dead-man's switch that could be selectively armed from C2.

And it established persistence through Claude Code and VS Code hooks.

That last one is why I stopped reading and went to check my own machine. The attacker's persistence mechanism was the tooling I use every day to write code. Not a cron job, not a systemd unit. An editor hook and an agent hook, in a config file I would never think to audit, running with whatever I'm running with.

They stopped attacking code

I wrote about vetting MCP servers a few days ago, and the attack in that piece was a different shape. Somebody published a hostile package under a name close to a real one and waited for people to install it. Careful reading of who published a thing would have caught it.

This one is worse, and everything I recommended in that article would have been less help than I'd like.

The package was legitimate. The maintainer was legitimate. The repository was the right repository under the right account with the right history. There was no impostor to detect, because the credential used to publish was the real credential. Checking the publisher gets you nothing when the publisher is who they say they are and someone else is holding their keys.

Which means the attack surface stopped being the code and became the person. And people, unlike code, get tired.

The economics are the vulnerability

The funding picture explains more than the incident does.

Tidelift's survey work puts roughly 60% of maintainers in the unpaid hobbyist category. The same research found 60% have quit or seriously considered quitting, with burnout named by 44% of them. The average unpaid maintainer puts in something like nine hours a week, and considerably more if their project got popular.

Then there's the finding that connects the two halves of this. Paid maintainers are 55% more likely to implement critical security and maintenance practices than unpaid ones.

That number reframes the whole conversation. Two-factor enforcement, scoped publishing tokens, signed releases, reviewing what a CI workflow can reach, rotating credentials after a laptop gets replaced. That's all work. It's unpleasant, unrewarding work, and it's the first thing to go when you're doing nine hours a week on top of a job and a family, on a project where the only feedback you get is bug reports.

So the compromise rate isn't independent of the funding rate. Attackers are targeting the softest credential in the chain, and we have collectively arranged for that credential to belong to somebody with no time, no budget, and no support.

Nobody attacked Ingress NGINX

The other failure mode doesn't involve an attacker at all.

In November the Kubernetes SIG Network and Security Response Committee announced that Ingress NGINX was being retired. It fully retired in March. No more bug fixes, no more security patches, no more releases of any kind.

That component was running in something close to half of cloud native environments.

The stated reason was people. The project ran on a tiny group of volunteers, sometimes one or two working in spare time, against what the announcement described as an endless flood of bugs and feature requests. They ran out.

Nobody exploited them. Nobody had to. A meaningful chunk of the world's production ingress is now unmaintained because the people holding it up put it down, and they were entirely within their rights to.

I find that scarier than the npm worm. A compromise gets discovered, disclosed, patched, and written about. This just quietly becomes your problem in eighteen months when a CVE lands against something that has no one left to fix it.

The asymmetry, again

I keep arriving at the same argument from different directions, so I'll name it plainly.

Somebody is absorbing a cost here, and it isn't the party benefiting most. Companies with real revenue build products on packages maintained by people earning nothing, then treat the resulting security incidents as an unfortunate feature of the ecosystem rather than as a consequence of how they've chosen to consume it.

Every technical control I'd recommend is individually sensible and collectively inadequate. Cooldown before you install a new version, which I do and which would have helped here. Pin exact versions. Scoped tokens, short-lived credentials, egress restrictions, per-project secrets so one stolen key doesn't unlock everything. Audit your editor and agent hooks now that they're a persistence target, which is new advice as of this month.

Do all of it. It's worth doing. It also amounts to every downstream consumer independently building a moat around a system whose actual problem is that its foundations are unfunded, and no arrangement of moats fixes that.

The boring answer

The fix that would move the number is money, and specifically money paid to the people maintaining the four or five packages your product would break without.

Not a foundation donation in the abstract. Go look at your lockfile, find the transitive dependencies with one maintainer and a million downloads, and send them something. GitHub Sponsors takes about ninety seconds. If you work somewhere with a budget, this is a smaller line item than one incident response engagement and it addresses a cause rather than a symptom.

I understand why this answer is unsatisfying. It isn't a tool, it doesn't scale through configuration, and there's no dashboard for it. It also happens to be the one intervention with research behind it, which is more than most of what we do in security can claim.

The next one of these will come from a compromised account belonging to somebody who was doing their best, unpaid, on top of a full time job. We know that in advance. Whether that's a tragedy or just the operating cost of the way we build software is up to what the people using the code decide to do about it.