# ChainDrop Hit 2 Billion Monthly Downloads. Provenance Attestation Didn't Stop It.
The Keyv GitHub account got compromised. Everything downstream followed.
That's the short version of ChainDrop, a self-propagating npm worm that has burned through more than 1,300 packages — including some of the most heavily depended-upon caching utilities in the Node.js ecosystem — and touched a combined 2 billion monthly downloads. The attack is still being contained as of Monday, and the full blast radius won't be known for days.
But the headline number isn't the real story. The real story is what ChainDrop did to one of the security community's most repeated defenses: *just verify provenance*.
## One Account, Then Everything
The attacker's entry point was the GitHub account of the maintainer behind Keyv, a lightweight key-value storage library that has become infrastructure-grade for a huge swath of Node.js applications. From that single foothold, ChainDrop spread to Cacheable, flat-cache, and file-entry-cache — all tools from the same maintainer, and all used heavily in build toolchains, CI runners, and developer workstations.
Then it jumped.
Because each infected package's own package.json now contained a "preinstall": "node setup.mjs" directive, anyone who ran npm install against a poisoned version automatically executed the dropper before the install even completed. No prompt, no warning. The npm package manager treated it as a standard lifecycle hook — which is exactly what it is, just weaponized.
From there, the worm searched the compromised environment for credentials it could use to reach *other* packages maintained by *other* people. Deliveroo, Ornikar, Picsart, ServiceTitan — the list of affected organizations' packages reads like a VC portfolio, not a targeted attack on any single company. That's the point. ChainDrop didn't need to find a new vulnerability. It turned one compromised maintainer account into a bridge to hundreds of others.
## The Provenance Problem
Here's what stings the most for anyone who has been selling supply-chain security tools over the last two years: the compromised packages carried valid provenance attestations.
The attacker didn't need to fake anything. They pushed malicious code to the project's main branch and let the legitimate GitHub Actions workflows do the rest — build the package, sign it, publish it to npm with all the right provenance metadata intact. From npm's perspective, the release looked identical to any other trusted release from that maintainer.
This is not a theoretical edge case. This is the exact scenario that provenance was supposed to help with, and it didn't, because the threat was upstream of the signing step. The chain of trust starts with the developer's GitHub account, and that's where the attacker was.
## What ChainDrop Actually Steals
The Math_Symbol.js infostealer is thorough. Not "thorough for malware" — just thorough. It goes after:
ghp_, gho_, ghs_ prefixes)npm_ prefix), validated in real-time against registry.npmjs.org/-/whoami before exfilWithDecryption: true, and Secrets Manager secretsThe validation step against npm's registry before stealing tokens is a notable detail — it's noise reduction, not caution. The attacker wants live tokens, not expired ones. That level of operational cleanup suggests this isn't a script kiddie running a found tool.
Stolen data was encrypted and sent to a public GitHub repository named — in a Dune reference that aged poorly — *"Shai-Hulud: Here We Go Again."* Cloud security firm Wiz flagged a second exfiltration channel via npm-cache[.]com, which should now be treated as a hard indicator of compromise in any environment where ChainDrop-affected versions were installed.
The self-hosting runner extraction code is particularly sharp: the worm specifically targets "isSecret":true values from GitHub Actions self-hosted runners, which are often where organizations put credentials they *don't* want in the cloud.
## If You Ran npm install This Weekend
The guidance from both Aikido and the broader security community is unambiguous and uncomfortable: treat the machine as compromised, not the package.
Removing the affected package version doesn't help. The setup.mjs dropper executed during npm install — before you could have known anything was wrong. If an affected version touched your workstation or CI runner, assume every credential that machine could access is now in someone else's hands.
That means:
npm-cache[.]com in DNS logs and firewall telemetryOrganizations with mature secret scanning should pull recent scan results for the environments that ran npm installs in the past week.
---
## HackWire Analysis
ChainDrop is a case study in how supply-chain attacks have evolved past the defenses the industry deployed after SolarWinds.
The post-SolarWinds response focused heavily on provenance: SLSA frameworks, Sigstore, build attestations. The logic was sound — if you can verify *where* a package was built and *by what workflow*, you can trust it more. ChainDrop proves that logic has a ceiling. When an attacker owns the developer's identity at the source, provenance doesn't fail gracefully — it *confirms* the attack.
This isn't entirely new territory. The 2021 ua-parser-js compromise and the 2022 node-ipc incident both exploited trusted maintainer accounts. What's different here is the worm behavior. ChainDrop didn't just infect the Keyv ecosystem; it actively sought out new maintainer credentials in each compromised environment to spread laterally into *unrelated* package trees. The blast radius is a function of the worm's reach, not just Keyv's footprint.
What's missing from most of the coverage: the credential scope ChainDrop targets is explicitly cloud-native. HashiCorp Vault, Kubernetes secrets, AWS SSM, self-hosted runner secrets — this isn't designed for compromising developer laptops. It's designed to pivot into production cloud environments via the CI/CD pipeline. The developer machine is a stepping stone, not the target.
For defenders, the immediate question isn't "was I infected?" — it's "did my CI runners touch npm install in the last week, and what did those runners have access to?" Any organization running self-hosted GitHub Actions runners with attached IAM roles or cloud credentials should treat this as a tier-one incident until proven otherwise.
The "Here We Go Again" in the exfil repo name may be bravado, or it may be accurate. Prior ChainDrop-adjacent activity hasn't surfaced yet publicly. It should be looked for.
— HackWire Editorial
---
## Related Coverage