Microsoft Threat Intelligence published its teardown of ChainDrop on Tuesday: a self-propagating credential-stealing worm that rode into more than 400 npm packages belonging to publishers who have nothing to do with one another. SecurityWeek, drawing on JFrog, StepSecurity and Socket, counts 2,212 malicious package versions across 440 packages — published in under four hours on August 4.
The entry point was ordinary. A maintainer’s GitHub account was compromised, which handed the attackers eleven packages in the keyv and cacheable namespaces. Those eleven have, by SecurityWeek’s count, more than 500 million weekly downloads between them. From there the worm did the work: 433 additional packages fell without anyone touching another account.
That propagation loop is the mechanically interesting part. Once the payload finds an npm publishing token, it enumerates every package that identity can reach, pulls the latest tarball, inserts itself, bumps the patch version, and republishes. Microsoft notes that most malicious releases had no matching source commit, pull request or tag — the attackers modified and published the archives directly. On a dependency dashboard it looks like a boring patch bump. That is the costume.
What it took, and from where
Execution happens through an npm preinstall lifecycle hook, which runs before installation finishes and therefore before your tests or scanners get a turn. Microsoft describes a payload that then sweeps developer workstations and CI/CD runners for npm, GitHub, cloud and infrastructure credentials, and uses whatever it finds to authenticate against npm, GitHub, AWS, Kubernetes and HashiCorp Vault — not pattern-matching for secrets in files, but calling the APIs to confirm the access is live and pull more.
Socket documented a dead-man’s switch: the implant checks the stolen GitHub token roughly every 60 seconds and deletes itself if the token stops working, and self-clears after 24 hours. Short-lived by design, which makes after-the-fact detection harder than the package count suggests.
The AI part
Here is the line in Microsoft’s report worth reading twice. Using stolen GitHub credentials, the payload injects itself into repository branches at four specific paths: .claude/settings.json, .claude/setup.mjs, .vscode/tasks.json and .vscode/setup.mjs.
Microsoft’s conclusion: “future Claude or Visual Studio Code activity can restart the payload even after the original npm installation has completed.” You clean the package. You purge the cache. Then a teammate opens the repo, the coding agent reads its project configuration the way it is designed to, and the thing comes back — on a machine that never installed the bad package at all.
Our take: Every AI coding tool ships with a checked-in config file, and the whole point of that file is that the agent trusts it and runs it without asking. We have spent two years teaching teams to review code and zero years teaching them to review .claude/settings.json, because it reads like preferences, not like executable surface. It isn’t preferences. ChainDrop did not need a novel exploit to use it — it needed a write token and the knowledge that nobody reads that diff. Treat your agent’s configuration directory as production code: pinned, reviewed, and owned by someone. The attackers already do.
What to watch
- Whether agent config files enter the review perimeter. Branch protection and required review normally cover source. Extending them to
.claude/and.vscode/is a one-afternoon change most teams have not made. - npm’s cooling-off lever. Microsoft’s first recommendation is npm CLI v12 with
min-release-age— refusing brand-new versions for a set window. Nearly every ChainDrop release was minutes old when it spread. - Whether rotation actually happened. Anyone who installed an affected version should treat that workstation or runner as compromised, rotate credentials from a known-clean host, and rebuild golden images so poisoned caches don’t get inherited. JFrog’s addition: preserve tarballs, npm logs, CI logs and GitHub audit logs before cleanup, or you lose the ability to bound the exposure window.
- The next namespace. This is the latest in a run of Shai-Hulud campaigns. The pattern — one stolen maintainer identity, then automated blast radius — is now repeatable enough to expect again.
The uncomfortable summary: the compromise arrived as a patch-version bump, spread through a token, and persisted through a file your AI assistant was built to obey.
