Open Source · · 1 day
keyv and cacheable maintainer compromise seeded the ChainDrop worm
On 2026-08-04 an attacker took over the jaredwray account and republished the keyv and cacheable families with a preinstall hook that downloaded Bun and ran a credential harvester. The worm spread to 444 package names and 2,212 versions in under four hours.
Part of ChainDrop worm poisoned 444 npm packages in four hours campaign
On August 4, 2026, an attacker took over the GitHub account of Jared Wray, the maintainer behind the keyv and cacheable npm families, and published malicious versions of ten widely used caching packages. Within four hours the worm those packages carried had poisoned 444 package names across 2,212 versions, reaching more than a dozen victim organizations.
The affected packages sit deep in the JavaScript dependency graph rather than at the top of it. keyv@6.0.0 has more than 150 million weekly downloads, flat-cache@6.1.24 around 149.9 million, and file-entry-cache@11.1.6 roughly 147.6 million. Very few developers install them deliberately. Almost everyone installs them. The publishing path is what made the releases hard to dismiss. Rather than pushing tarballs by hand with a stolen npm token, the attacker committed malicious files directly to the main branch and immediately cut a release, so the poisoned versions went out through GitHub Actions with valid provenance attestations. Every package received two new files, setup.mjs and Math_Symbol.js, plus a "preinstall": "node setup.mjs" entry in package.json. The hook downloaded a standalone Bun runtime and executed an obfuscated second stage before npm install returned.
The payload collected npm and GitHub tokens, AWS credentials, HashiCorp Vault secrets, database connection strings, and private keys, and read GitHub Actions runner memory for secrets that never touch disk. It planted autostart hooks in .claude and .vscode directories so that a developer cloning affected source would run it again. Then it republished trojanized versions of every package the stolen token could reach, using npm's OIDC trusted publishing to mint credentials under legitimate workflow identities.
StepSecurity, which named the worm ChainDrop, documented the part that most interested defenders: the exfiltration endpoint was not hardcoded. The malware queried an Ethereum smart contract at 0xE1f2395ee43e45A1556EC6438a88c31B83493103 to retrieve the current address at runtime, rotating through roughly 60 public Ethereum RPC endpoints until one answered. Late on August 4, researchers watched the operator reconfigure the entire C2 infrastructure with a single Ethereum transaction, without touching the deployed malware. Wiz assessed the payload as a descendant of the Mini Shai-Hulud family used in the TeamPCP and AntV campaigns earlier in the year.
Notes
- The malicious versions carry valid provenance. The attacker pushed to the main branch and cut releases through GitHub Actions rather than publishing with a stolen npm token, so provenance attestation does not distinguish them from legitimate releases.
- Counts vary slightly by source and collection time. StepSecurity reported 444 packages and 2,212 versions in under four hours; other trackers reported 2,234 to 2,236 versions and 400-plus packages as the campaign continued.
- npm registry publish times for the three recorded carriers: keyv 6.0.0 at 09:35:00Z, flat-cache 6.1.24 at 10:10:55Z, and file-entry-cache 11.1.6 at 10:13:02Z on 2026-08-04. keyv 6.0.0-rc.1 was published at 19:21:08Z on 2026-08-03, before the reported window; no source classifies it, so it is not recorded as malicious. It also remains served by the registry, while the three recorded carriers return 404, which is consistent with leaving it unclassified.
- keyv 6.0.0, flat-cache 6.1.24, and file-entry-cache 11.1.6 were removed from npm and their original registry tarball URLs now return 404. Retained Socket member manifests and Forager partial recovery yielded complete, verified member-tree reconstructions for flat-cache and file-entry-cache and a six-of-nine partial reconstruction for keyv. The synthetic gzip streams remain explicitly named RECONSTRUCTED because their original archive bytes have not yet been recovered. The immediate predecessors flat-cache 6.1.23 and keyv 5.5.3 remain served by npm.
- The Ethereum dead-drop lets the operator rotate exfiltration infrastructure without redeploying malware. Researchers observed a full C2 reconfiguration through a single transaction late on 2026-08-04.
- Wiz assessed the payload as a descendant of the Mini Shai-Hulud family, sharing characteristics with the TeamPCP and AntV campaigns recorded under [[shai-hulud-here-we-go-again]].
Appendix · Affected releases
- Reported at more than 150 million weekly downloads.
- Socket mapped the SHA-512 checksum to the complete keyv-6.0.0.tgz npm distribution archive.
- OSSF MAL-2026-11524 maps the SHA-1 checksum to that same complete keyv-6.0.0.tgz archive.
- OSSF MAL-2026-11970 maps these checksums to the complete file-entry-cache-11.1.6.tgz npm archive.
- Reported at roughly 147.6 million weekly downloads.
Indicators
- filesetup.mjs
- fileMath_Symbol.js
- ethereum_contract0xE1f2395ee43e45A1556EC6438a88c31B83493103
- malware_familyChainDrop
References
- ChainDrop npm Worm: Bun-loaded CI/CD credential harvester with Ethereum dead-drop C2 - StepSecuritystepsecurity.io
- Popular npm Packages in the keyv and Cacheable Namespaces Compromised in Active Supply Chain Attack - Socketsocket.dev
- keyv and cacheable npm Package Hijacked in Supply Chain Attack - Wizwiz.io
- Inside the keyv npm Supply Chain Compromise - Snyksnyk.io
- Shai-Hulud strikes again: CHAINDROP worm hits 400+ npm packages - Elastic Security Labselastic.co
- Major Shai Hulud campaign strikes npm again, affecting keyv and 400+ packages - JFrog Security Researchresearch.jfrog.com
- Keyv and friends compromised in active Shai-Hulud supply chain attack - Aikidoaikido.dev
- keyv and cacheable npm compromise: 400+ packages - SafeDepsafedep.io
- OSSF malicious-packages databasegithub.com
- OSSF MAL-2026-11524 package-integrity record for keyv 6.0.0raw.githubusercontent.com
- Socket retained member manifest for malicious keyv 6.0.0socket.dev
- Socket retained member manifest for adjacent clean keyv 5.5.3socket.dev
- Socket retained member manifest for malicious flat-cache 6.1.24socket.dev
- Socket retained member manifest for malicious file-entry-cache 11.1.6socket.dev
- npm registry version metadata for checksum-verified keyv 6.0.0-rc.1 reconstruction inputregistry.npmjs.org
- Exact retained malicious keyv 6.0.0 release source commitgithub.com
Source record: oss/attacks/keyv-cacheable/meta.yaml