The scary thing about software supply chain attacks is not that they happen. It’s how little has to go wrong.
In this case, nothing obvious was stolen. No one got phished. No password leaked. The packages were published through the very mechanism meant to prevent this sort of thing: trusted publishing. That is what makes the attack interesting.
The weakness was not npm’s signing. It was a workflow.
A project used pull_request_target, which is one of those features that sounds convenient when you’re setting it up and ominous when you understand it. A pull request from a fork could run with the main repository’s permissions. The attacker created one, closed it, and used that brief opening to poison the CI cache.
That was enough.
Later, when a real change was merged, the poisoned cache woke up, grabbed a short-lived npm token, and published compromised packages. Then the malware did what worms do: looked for more credentials, found maintainers’ publish tokens, and spread outward through their packages too.
This is why supply chain attacks are hard. Modern systems are full of components that are individually reasonable and collectively dangerous. Signed attestations, short-lived tokens, CI caches, editor extensions, install scripts—none seem crazy on their own. The problem is the seams.
The obvious lesson is to configure workflows more carefully. Don’t run privileged jobs on untrusted pull requests. Don’t share caches casually. Delay adoption of freshly published packages. Block install scripts by default.
But the deeper lesson is that security now depends less on secrets than on ambient authority. The attacker doesn’t need your password if your machinery will act on his behalf.