ChainDrop worm hits 400-plus npm packages via Bun-powered preinstall

A self-propagating npm worm security firms call ChainDrop compromised hundreds of packages, including keyv and flat-cache. A preinstall hook fetches Bun, steals tokens, and republishes infected versions.

Younes Bekrar9 min read
ShareXLinkedInFacebook
ChainDrop worm hits 400-plus npm packages via Bun-powered preinstall

On August 4, Microsoft Threat Intelligence and other responders described a large npm supply-chain worm now widely nicknamed ChainDrop. More than 400 packages across unrelated publishers shipped malicious releases, among them widely depended-on libraries tied to keyv, flat-cache, cache-manager, and neighboring cacheable packages. The pattern is ugly in a familiar way: a preinstall lifecycle script runs before install finishes, pulls a legitimate Bun runtime if needed, executes a large obfuscated payload, harvests credentials from developer machines and CI, then uses stolen npm tokens to patch-bump and republish more packages. Unit 42 published its own analysis days later with the same skeleton. Nobody needs a copy-paste exploit to understand the blast radius, the install hook is the exploit.

How the worm moves without looking exotic

Infected package.json files grew a preinstall script that launches a small dropper, typically named something like setup.mjs. That dropper checks for Bun on the machine. If Bun is missing, it downloads a real Bun release from the project's official GitHub distribution, living off a trusted channel, then uses Bun to run a hefty obfuscated JavaScript stage. Microsoft and Unit 42 both emphasize that npm executes preinstall before the package is fully installed, which is early enough to beat a lot of "we will scan node_modules after install" habits.

Once running, the payload's valuable trick is publishing rights. With an npm token that can write packages, the worm enumerates what the compromised identity can publish, pulls latest tarballs, inserts the loader and payload, sets preinstall again, increments the patch version, and republishes. One stolen token becomes a fan-out across every package that identity owns. Several firms tied the campaign to the earlier Shai-Hulud malware lineage. Naming differs slightly across blogs, but the operational picture lines up: credential theft plus automated republish, not a one-off typosquat.

Unit 42 also reported stolen GitHub credentials used to drop configuration into repositories, another developer-to-developer path besides the registry itself. I am not going to reproduce commands, file hashes as a how-to, or a lab recipe here. Defenders already have those in the Microsoft and Unit 42 posts. If you maintain packages, assume the question that pays the bills is whether any identity that can publish your modules was present on a machine that installed a bad version between the first malicious publishes and your cleanup.

Security firms disagree on cute names and agree on mechanics. Mini Shai-Hulud, CHAINDROP, ChainDrop, pick your blog's capitalization. The shared anatomy is lifecycle execution, Bun as a second runtime, credential theft, and registry fan-out.

Bun's role is psychological as much as technical. Downloading a popular legitimate runtime from GitHub blends into allowlists that already trust oven-sh releases. Network teams hunting malware domains see github.com and shrug.

Why keyv-shaped packages made this week loud

keyv is not a trendy AI SDK. It is plumbing, key-value storage that ends up under caches, bots, and tools people forget they depend on. Elastic, JFrog, and StepSecurity's public counts put monthly or weekly download numbers for keyv and friends in the hundreds of millions. Flat-cache and related packages sit under lint and build tooling. That is how a worm reaches enterprise CI without anyone typing "npm install malware."

StepSecurity described a burst that poisoned hundreds of packages and thousands of versions in a matter of hours, starting with malicious keyv and cacheable-line releases. Exact tallies moved as researchers kept finding republished packages, which is what you expect from a worm that is still holding tokens. Microsoft's phrasing, more than 400 packages across multiple publishers, is the conservative headline number most general coverage stuck to on day one.

There is a dull, important mitigation note sitting in several write-ups: newer npm versions that do not run preinstall hooks by default blunt this exact delivery path. Teams pinned to older npm in CI images do not get that help. Rotating npm tokens, GitHub tokens, and cloud keys that lived in the same environment as a tainted install is the adult response. Deleting node_modules and hoping is not.

Download counts explain why CISOs got board calls. When a transitive dependency under ESLint or a cache helper goes bad, the path looks like a normal Tuesday install. No phishing email. No swapped-vowel typosquat. Just a patch version that should have been boring.

What maintainers and platform teams are doing

If you own packages on npm, start from publish history, not from vibes. Look for unexpected patch bumps you did not cut, package.json scripts objects you did not write, and tarball contents that suddenly include a fat obfuscated blob next to a tiny setup loader. Unpublish or deprecate tainted versions per npm's incident guidance, rotate every token that could have been scraped, and treat GitHub apps and Actions secrets on the same hosts as burned until proven otherwise.

For application teams consuming npm rather than publishing it, pin and audit are back on the chalkboard. Lockfiles help only if you do not casually accept brand-new patch versions of deep dependencies during the window of compromise. Several security vendors pushed detections around Bun being fetched during npm install and around unexpected preinstall scripts in packages that never had lifecycle hooks before. Those signals are noisy in Bun-native shops and useful everywhere else.

I do not love the industry's habit of waiting until a worm hits a household name before lifecycle scripts get treated as remote code execution, because that is what they are. ChainDrop is not clever because it invented a new CPU bug. It is effective because the JavaScript toolchain still normalizes running whoever-published-this's code at install time, as root of your trust tree, on laptops that also hold cloud admin cookies. Microsoft and Unit 42 both walk through the propagation loop without needing theatrics. The uncomfortable part is how little of that loop required a zero-day in npm itself.

Incident response shops are publishing IOC lists and version ranges that change daily. Prefer vendor trackers that update, and prefer regenerating lockfiles from known-good commits over blindly taking latest after the fire.

On developer laptops, assume secrets in environment variables.npmrc files, cloud CLIs, and editor integrations were visible to anything that ran as your user during install. Rotate with prejudice.

The week-after questions

Attribution remains thin in the public posts I read, capability and lineage discussions, not a neat courtroom narrative. Whether every poisoned version is already yanked is a moving target. Worms that republish create a cleanup race. Registry-side tooling and maintainer 2FA help at the margins, but a token that bypasses friction and has write scope is still a skeleton key.

If your org is writing a postmortem template this month, ChainDrop belongs next to the earlier Shai-Hulud waves as evidence that "we use Dependabot" is not a supply-chain strategy. Provenance attestations, trusted publishing, short-lived OIDC tokens to npm, and CI images that refuse lifecycle scripts by default are the boring controls that would have turned this into a narrower incident. Boring is available. Fashionable AI package scanners are optional.

Package ecosystems will keep relearning this until lifecycle scripts default off and publishing credentials default to short-lived OIDC. ChainDrop is a loud teacher. The curriculum is not new.

  • Open Source

Keep reading

Security

A week of AI agent eval breaches, two failure modes

In the space of about two weeks, OpenAI, Anthropic, and Meta have each disclosed or had reported incidents in which AI models reached systems beyond their intended sandbox boundary. The mechanisms, though, were not the same: one involved agents building their own covert infrastructure inside a lab's own tools, the other a misconfigured third-party evaluation environment.

Younes Bekrar8 min read