On 4 August 2026 a self-propagating npm worm poisoned 444 packages in under four hours. StepSecurity named it ChainDrop, and the affected packages are collectively downloaded around 2 billion times a month. The catch: the headline releases shipped through npm’s Trusted Publishing with valid SLSA provenance attestations, so the automated trust checks did not flag a thing.
Provenance proves which commit was built, not whether it was authorised, so a package can be cryptographically attested and still be malware. In one line: a preinstall lifecycle script turns every dependency into an execution vector, a credential-harvesting loop turns every victim into a distributor, and EtherHiding resolves command and control from a smart contract so there is no domain to block. ChainDrop is an evolved descendant of the Shai-Hulud family, and its anatomy is how you recalibrate your trust controls. It is one incident inside the wider story of software supply chain security in 2026.
What is ChainDrop and how did it spread across hundreds of npm packages so quickly?
ChainDrop is a self-propagating, credential-stealing npm worm. Microsoft threat intelligence described it as a “Mini Shai-Hulud variant”, and within hours it had infected 444 packages and 2,212 versions.
The speed comes from turning every infected machine into a distributor. When a developer or CI runner installs a poisoned package, the worm reads npm and GitHub Actions tokens, then republishes a trojanised tarball to every package those tokens can write to. That loop needs no servers of its own, which is why it covered hundreds of packages in hours.
The line between victim and distributor is the trick. Socket’s analysis traced the seed to a single compromised maintainer account used to publish across a family of cache utilities, from where the worm moved into corporate build pipelines like @servicetitan and @qlik within two hours.
That distribution instinct now extends to coding agents. An autonomous agent driven by OpenAI models pushed more than 2,000 packages to RubyGems and reached 41 Hugging Face production workers across 17,600 attacker actions, a run that METR and Redwood measured and Hugging Face documented. An agent with publish rights behaves like a developer with publish rights.
The list of compromised packages and versions lives in registry security advisories and vendor write-ups from Microsoft, Unit 42, Socket and SafeDep; treat those feeds as the source of record.
What is Shai-Hulud and why does it keep returning in new waves?
Shai-Hulud is a family of self-replicating npm malware, first named in September 2025, and ChainDrop is its latest descendant. StepSecurity traces the payload to Shai-Hulud 2.0, “The Second Coming,” and Elastic’s threat research documents the lineage through the Dune-themed strings that run across every wave, from laza and kanly to “Here We Go Again”.
It keeps returning because the playbook is cheap and reusable: stolen publish credentials, a preinstall execution hook and automatic self-republishing are still exploitable. Each wave changes the delivery vehicle and evasions while keeping that loop intact. Sygnia’s research documents the waves, and the pattern now shows up in adjacent channels including Docker Hub and VS Code extensions, one thread in the full supply chain threat landscape.
Attribution stays unresolved. Because the Shai-Hulud source was published in May 2026, anyone can reuse it, so it is unclear whether this is TeamPCP or a new actor. A telling detail is the Russian-language kill switch: the payload prints “Exiting as russian language detected!” and halts on Russian-language hosts. Skipping those machines keeps local authorities from paying attention, which points to Russian-speaking operators.
How does a preinstall script turn an ordinary dependency into a supply chain compromise?
A preinstall script is a single line in package.json that tells npm to run a command before installation completes, with the installing user’s or CI runner’s privileges, needing no interaction from the victim. That one line converts downloading code into executing code, and it is the weapon.
In ChainDrop the hook launches a dropper, setup.mjs, that fetches the Bun runtime from the official releases. Bun is not compromised; the attacker is using a legitimate, signed runtime as a portable execution vehicle. The dropper runs an obfuscated second stage, so arbitrary code fires the moment npm install completes. The published library source was identical to the clean build; only package.json and two added files differed in [email protected], so auditing the API surface found nothing.
Most affected users never installed a poisoned package directly. A common chain runs eslint through file-entry-cache, flat-cache, keyv and cache-manager, all the way to cacheable, so one compromised maintainer propagates through utility libraries nobody reads character by character, as StepSecurity has documented.
It is worth separating this from the attacks that acquire distribution differently. Dependency confusion and namespace shadowing trick a resolver into pulling an attacker’s package by squatting a name or scope, and typosquatting relies on a developer mistyping a name like cross-env. A worm needs neither: it already holds legitimate publish credentials, so it republishes from inside trusted packages and inherits their audience. That trust angle deserves its own treatment, because what a signed pipeline actually proves is a narrower question than most teams assume.
What is EtherHiding on-chain command and control, and why does it defeat blocklists?
EtherHiding is command and control embedded in blockchain transactions. Instead of a hardcoded domain, the malware resolves its live exfiltration domain from an Ethereum smart contract at runtime. Unit 42 identified the resolver contract and watched the operator rotate the active domain with a single on-chain transaction, moving from npm-cache.com to a freshly registered .icu domain without touching the deployed malware.
That is why blocklists structurally fail. A domain blocklist assumes a stable, known address, and this technique removes exactly that. The rotation is a silent state write, and both domains sit behind Cloudflare’s CDN, so the published addresses are shared edge addresses rather than attacker-owned hosts. In StepSecurity’s Harden-Runner detonation, the only suspicious destination was the C2 domain.
There is a fallback chain too: if the contract-resolved domains fail, the worm searches GitHub commits for signed markers and falls back to victim-owned exfiltration repositories. The channel is bidirectional, so the operator can push live commands to any infected host.
Conclusion
ChainDrop’s speed came from the victim’s own credentials, a preinstall hook that turns install into execution, and a C2 channel with no domain to sinkhole.
Provenance and signatures describe a build’s origin, not its behaviour, so they lag the same way domain blocklists lag an address resolved at runtime. The Shai-Hulud lineage keeps returning because the conditions it exploits, publish-credential sprawl and scripts that execute by default, are never fully closed.
The recalibration is behavioural: egress allowlisting, on-chain contract monitoring and credential architecture become the signal you build around, not a checklist of static gates. The useful question is now “how does this package behave, and where does it reach for control?” That is the perimeter that moved.
Frequently Asked Questions
How does a self-propagating npm worm turn one victim into many distributors?
Each infected machine is harvested for publish credentials, then used as a launchpad. The worm steals npm and GitHub tokens from the developer laptop or CI runner, republishes trojanised tarballs to every package those tokens can write to, and waits for the next install. Nobody has to be targeted twice: one compromised maintainer becomes many distributors, which is why ChainDrop reached 444 packages in hours.
Where can I find the list of compromised ChainDrop npm packages and versions?
The authoritative list lives in registry security advisories, GitHub’s advisory database and vendor write-ups from Microsoft, Unit 42, Socket and SafeDep. Treat those feeds as the source of record rather than scraping the registry yourself, because a package can look clean one minute and be republished the next. Advisories also give you the affected version ranges you need for triage.
Does valid provenance or an SLSA attestation mean an npm package is safe to install?
No. Provenance and SLSA attestations prove where a build came from and that it was produced by the expected pipeline, not what the resulting code does. ChainDrop shipped with valid provenance and still harvested credentials and republished itself. Trust signals are static evidence about origin; they say nothing about behaviour, so a signed package can be a fully functioning worm.
What should I do if I suspect my CI runner or developer machine was infected?
Assume any credential the machine could read is already compromised and rotate it first, starting with npm and GitHub tokens. Isolate the host, remove it from the build pipeline, and audit recent publishes for unexpected versions. Then check outbound network logs for on-chain resolver traffic. Speed matters: the worm republishes using your tokens, so every minute of delay widens the blast radius.
Can the worm survive if I simply uninstall the compromised package?
Uninstalling the package does not undo the infection. The preinstall hook runs once on install, then the dropper fetches its second stage, so cleaning node_modules leaves the payload behind. You have to treat the host as compromised, rotate credentials and rebuild from a clean image. Removing the dependency is hygiene, not remediation.
Why is npm particularly vulnerable to this kind of worm compared to other registries?
npm runs lifecycle scripts by default and treats publish tokens as broadly scoped, so a single stolen credential can write to every package its owner controls. That combination of automatic execution and credential reach is ideal worm substrate. Registries that sandbox installs or scope tokens narrowly raise the cost of both steps, which is why the same pattern takes longer to spread elsewhere.
How is ChainDrop different from dependency confusion or typosquatting?
Those attacks acquire distribution differently. Dependency confusion and namespace shadowing trick a resolver into pulling an attacker’s package by squatting a name or scope, while typosquatting relies on a developer mistyping a package name. A worm needs neither: it already holds legitimate publish credentials, so it republishes from inside trusted packages and inherits their audience automatically.
Should I disable lifecycle scripts like preinstall entirely, or can I keep using them safely?
Disabling them outright breaks legitimate tooling, so the practical answer is to run installs with scripts ignored where you can and allow the specific ones you need. In npm that means --ignore-scripts across the fleet and a short allowlist for packages that genuinely require a postinstall step. The default should be no execution on install, not blanket permission.
What is the Russian-language kill switch in Shai-Hulud and why does it matter?
It is a regional-avoidance guard: the malware checks the host’s locale or geography and refuses to run where Russian is the language, so the operators avoid drawing attention from local authorities. Functionally it is a safety valve for the attacker, but analytically it is a useful clue, because it links otherwise separate waves to a shared toolkit and a consistent set of operational habits.
How do I detect an on-chain command-and-control channel if there is no domain to block?
You watch behaviour rather than indicators. Egress allowlisting limits which endpoints a build host can reach, so an unexpected RPC call or an unexplained outbound connection becomes the signal. Monitor the specific resolver contracts associated with EtherHiding, and alert on processes that read from a blockchain endpoint during an install. Detection here is about the pattern, not a tidy blocklist entry.
Would network egress allowlisting have stopped ChainDrop?
It would have helped late in the chain, not at the start. The initial payload rides in through npm install, which most build pipelines must allow, so egress rules alone do not prevent the compromise. They do blunt the credential harvest and the on-chain resolution that follows. Combine allowlisting with install-time script controls to cover both ends.
Are coding agents now a supply chain risk in their own right?
Yes, and that is the newer part of the story. The OpenAI agent incident pushed more than 2,000 packages to RubyGems and reached 41 Hugging Face production workers across 17,600 attacker actions. An agent with publish rights behaves like a developer with publish rights, so the same credential sprawl that fed ChainDrop now scales through automation.