ChainDrop npm worm hit 435 packages in under 3 hours
A self-propagating npm worm compromised 435 packages and 1,557 versions on August 4, harvesting CI tokens, cloud keys, and Claude credentials. What to do today.
If a build ran on your CI this morning, go look at what it pulled down. A self-propagating npm worm called ChainDrop spent roughly two and a half hours on August 4 republishing itself across the JavaScript ecosystem, and the packages it landed in are not obscure — they're the ones sitting three levels deep in your dependency tree that nobody has thought about in years.
What actually happened
Per StepSecurity's analysis, the first wave started at 09:02 UTC. The attacker compromised GitHub accounts behind three repositories — keyv, cacheable, and ecto — and injected malicious files into 11 packages. Those packages published through the maintainer's own GitHub Actions workflows, which means they carried valid SLSA provenance attestations. The supply-chain signal most teams treat as proof of authenticity signed the malware.
The second wave ran until 11:44 UTC. Using tokens stolen from the first victims, the worm republished itself into 424 more packages, including scoped org packages like @servicetitan, @qlik, and @onereach. Final count: 435 packages across 1,557 versions. keyv@6.0.0 alone moves 153.7 million weekly downloads.
The payload is two stages. A setup.mjs dropper pulls the legitimate Bun runtime from GitHub's official releases, then executes Math_Symbol.js, a 727KB obfuscated worm. It harvests npm and GitHub tokens — including scraping secrets out of GitHub Actions runner memory via /proc/<pid>/mem — plus AWS credentials across 16 regions, kubeconfigs, Vault tokens, SSH keys, Docker configs, and credentials for Claude, GitHub Copilot, and VS Code. Then it publishes itself everywhere those tokens reach. C2 domains aren't hardcoded: the worm resolves them from an Ethereum mainnet contract queried across 75 public RPC endpoints, so there's no domain to sinkhole.
Why it matters for your business
Two details make this worse than the usual npm incident. First, provenance held and the package was still malicious — a compromised maintainer account produces perfectly attested poison. Second, it writes persistence into .claude/settings.json and .vscode/tasks.json, so the payload re-fires when a developer opens the repo or starts an AI coding session. Your laptop gets hit after the registry is already cleaned up.
If you deploy Node anything, today's work is concrete: pin affected packages with npm overrides, run installs with --ignore-scripts, and rotate every credential that touched a build in that window — npm tokens, cloud keys, SSH keys, CI secrets. Then fix the standing posture: a minimum release age of 3–7 days before auto-updating dependencies would have blocked this entirely, and egress controls on CI runners would have stopped a build box from downloading a runtime it never asked for.
Key takeaways
- ChainDrop compromised 435 npm packages across 1,557 versions between 09:02 and 11:44 UTC on August 4, 2026, starting from
keyv@6.0.0 - Malicious versions shipped with valid SLSA provenance because they published through the real maintainer's GitHub Actions workflows
- It steals npm/GitHub tokens, AWS keys across 16 regions, kubeconfigs, Vault tokens, and Claude/Copilot credentials — then republishes itself with them
- Rotate anything exposed to a build in that window; add a 3–7 day minimum release age and CI egress controls so the next one doesn't reach you
Not sure what your build pipeline actually pulls? We audit dependency trees, lock down CI runners, and set up release-age gates so a compromised upstream package doesn't become your incident. See how we harden builds or book a call.
Sources: StepSecurity.
- #npm
- #supply-chain
- #security
- #ci-cd
- #dependency-management
Tommy Rush — Founder, Rush Commerce
Operator turned builder. 15+ years running operations — now shipping the systems businesses run on. More
Get The Rush Report weekly — one email, zero fluff.
Keep reading
Phishing on Microsoft's real login page: MFA won't save you
A campaign hit ~120 organizations by sending users to the genuine login.microsoftonline.com and asking them to approve an app. OAuth consent phishing beats MFA.
Read itDiffusers CVEs: trust_remote_code was never a real gate
Three CVEs let a Hugging Face model repo run arbitrary code even with trust_remote_code=False. Upgrade to Diffusers 0.38.0 and pin your model revisions.
Read it