Campaign · Open Source · · 1 day

ChainDrop worm poisoned 444 npm packages in four hours

ChainDrop began with the compromise of the keyv and cacheable maintainer on 2026-08-04 and spread to 444 package names across 2,212 versions in under four hours, taking in servicetitan, ornikar, qlik, and nebula.js among others.

Draws together 1 incident across 3 packages

A self-propagating npm worm that researchers named ChainDrop spread through the registry on August 4, 2026, poisoning 444 package names across 2,212 versions in under four hours and touching more than a dozen victim organizations, among them ServiceTitan, Ornikar, Qlik, and nebula.js.

It started with one maintainer. The operator took over the GitHub account behind the keyv and cacheable package families, committed a preinstall hook to the main branch, and cut releases through the project's own GitHub Actions workflow, which meant the poisoned versions carried valid provenance. From there the worm used what it stole. Every set of npm credentials it harvested became publishing rights for the next round of packages, and it minted fresh tokens through npm's OIDC trusted publishing where a workflow identity allowed it.

The payload was a credential harvester aimed squarely at build infrastructure: npm and GitHub tokens, cloud credentials, SSH keys, database connection strings, and secrets read directly out of GitHub Actions runner memory. It also wrote autostart hooks into .claude and .vscode directories, so a developer who merely opened affected source would run it.

The operational novelty was the command-and-control channel. Rather than hardcoding an exfiltration endpoint, ChainDrop queried an Ethereum smart contract at runtime to learn where to send its results, cycling through roughly 60 public RPC endpoints until one responded. Blocking any single provider accomplished nothing, and late on August 4 researchers watched the operator move the entire C2 infrastructure with one transaction, without shipping a malware update. StepSecurity matched the payload byte-for-byte against Shai-Hulud 2.0, the November 2025 worm, on markers including the Bun preinstall dropper and a verbatim memory-dump grep. Unit 42 agrees on the code lineage but says plainly that it cannot yet tell whether TeamPCP runs it or another group adapting the published toolkit.

Notes

  • The origin compromise is recorded separately at [[keyv-cacheable]]. This record holds the campaign aggregate.
  • Package and version counts differ by source and collection time, ranging from 400-plus to 444 package names and from 2,212 to 2,236 versions. The keyv and cacheable families contributed the initial 10 to 11 carriers.
  • ChainDrop descends from Shai-Hulud 2.0, the November 2025 generation, on StepSecurity's byte-level markers, not from the May 2026 TeamPCP wave tracked under [[shai-hulud-here-we-go-again]]. Unit 42 declines to name the operator.

Incidents in this campaign

  1. keyv and cacheable maintainer compromise seeded the ChainDrop worm

Appendix · Affected packages

keyv 2026-08-04
6.0.0
flat-cache 2026-08-04
6.1.24
file-entry-cache 2026-08-04
11.1.6

Samples and hashes sit on each incident page, linked above

References

  1. ChainDrop npm Worm: Bun-loaded CI/CD credential harvester with Ethereum dead-drop C2 - StepSecuritystepsecurity.io
  2. Shai-Hulud strikes again: CHAINDROP worm hits 400+ npm packages - Elastic Security Labselastic.co
  3. ChainDrop: Inside a Self-Propagating npm Worm - Unit 42unit42.paloaltonetworks.com
  4. Over 400 NPM Packages Infected in ChainDrop Supply Chain Attack - SecurityWeeksecurityweek.com

Source record: oss/campaigns/chaindrop-2026/meta.yaml