If your remediation for ChainDrop was pinning safe versions and rotating npm tokens, you are probably still infected. The malicious packages are gone. The worm's second infection route never lived in a package at all — it lives in two configuration files that your software composition analysis tool does not read, your code review process does not cover, and your endpoint agent does not flag.
Those files are .claude/settings.json and .vscode/tasks.json. One re-launches the dropper the next time a developer starts a Claude Code session in that repository. The other re-launches it the moment anyone opens the folder in VS Code. Neither requires npm install. Neither is touched by a lockfile.
What ChainDrop Left Behind After the Packages Were Pulled
ChainDrop planted an executable foothold inside repository-level AI agent configuration, and that foothold outlives every dependency fix you have applied this week.
The dependency half of the story is the part everyone covered. Starting around 09:02 UTC on 4 August 2026, an attacker with a maintainer's GitHub account pushed poisoned commits into three repositories and cut immediate releases, according to StepSecurity's timeline, landing keyv@6.0.0, flat-cache@6.1.24 and file-entry-cache@11.1.6 on the registry. A "preinstall": "node setup.mjs" hook did the rest. CSO Online reports that npm began removing the malicious versions within about two hours and the maintainer regained the account near 20:00 UTC the same day. Counts differ by who is counting: StepSecurity and CSO put it at 444 packages across 2,212 versions, Aikido Security logged 444 packages across 1,381 versions by the following afternoon, and Microsoft Threat Intelligence says simply "more than 400." The combined install volume behind them is about two billion a month.
Two hours to the first removals, against two billion monthly installs, is bad — and the worm kept publishing well past that window, with StepSecurity still counting fresh poisoned versions at 18:10 UTC. It is also, in the end, bounded, well understood, and fixable with a pinned version.
The unbounded part is what the payload wrote to disk. StepSecurity documents the worm planting a SessionStart hook in .claude/settings.json that executes node .vscode/setup.mjs, plus a task in .vscode/tasks.json carrying "runOn": "folderOpen", alongside .claude/setup.mjs and .vscode/setup.mjs droppers — 29,918 bytes in the first wave, 11,017 in the second — and a 727,680-byte math_init.js stage two. Microsoft's own write-up names the same four paths. And where the worm held a stolen GitHub App token, it did not stop at the local disk: Elastic Security Labs found it committing those hooks into as many as 50 repository branches, authored as claude@users.noreply.github.com under the commit message chore: update config. Zero Hunt's analysis records the same impersonation using claude <noreply@anthropic.com> and github-actions[bot].
Read that sequence again as an org chart problem rather than a malware problem. A commit that appears to be from your own automation, with a boring message, touching a config file nobody reviews, in a branch nobody is watching — and it detonates on the ordinary act of opening the repo.
Why Dependency Remediation Never Touches These Files
Every control you applied this week operates on the dependency graph, and none of these files are in it.
Software composition analysis reads package.json, the lockfile and the resolved tree. .claude/settings.json is not a dependency; it is project configuration, and by design it is checked into source control and automatically active when you open the project, per Anthropic's own documentation. The same documentation confirms hooks "run wherever Claude Code runs," in the current working directory with Claude Code's environment, and fire automatically when their matcher conditions are met — there is no per-hook confirmation prompt. SessionStart fires when a session begins or resumes. That is the whole exploit. There is no vulnerability being used here. The feature works exactly as documented.
.vscode/tasks.json has the same shape with one important difference, which we will come back to.
The consequence is that a team can do everything right and stay compromised. You pinned keyv@5.6.0. You purged the npm cache. You rotated the publishing token. Your SCA dashboard is green. And the next engineer who clones that repo and runs an agent against it re-executes stage two, from a file that has been sitting in git looking like configuration for three days.
Look at what the official guidance actually tells people to do. Singapore's Cyber Security Agency issued its advisory on 6 August, two days after the compromise, with a competent and complete remediation checklist: remove malicious versions from development, build and CI/CD, treat systems as compromised and rebuild, rotate cloud credentials and GitHub tokens and SSH keys and Kubernetes configs, review cloud and source environments, monitor the published domains and hashes, tighten dependency allowlisting. Every item on that list is about packages, credentials or infrastructure. Agent configuration files are not on it. A team that follows a national CERT advisory to the letter still gets reinfected on session start.
The Credentials That Were Never on Your Rotation List
ChainDrop's collector went after AI agent credentials specifically, and those keys are almost certainly missing from your rotation inventory.
StepSecurity counted roughly 140 harvested file paths, and the AI-specific ones are worth reading as a list: .claude/credentials.json, .codex/auth.json, .cursor/credentials.json, .openai/auth.json, .anthropic/auth.json. Elastic puts the total credential pattern count above 300 and names Anthropic, Claude, Codex, Cursor, OpenAI and Gemini among the targets. Zero Hunt makes the point that matters commercially: these are frequently org-billed keys with generous rate limits and, increasingly, tool-execution scopes.
Tool-execution scope is the phrase to sit with. An AWS key stolen from ~/.aws is a known quantity — you have a rotation runbook, a detection rule and a blast-radius estimate for it. A Cursor or Codex or Gemini CLI credential with agentic scope is a key that can read repositories, run commands and call MCP servers, billed to your account, and in most organisations it was provisioned by a developer through a self-serve signup and has never appeared in an identity inventory. We have written before about machine identities outnumbering humans 109 to 1 and about AI agents holding keys nobody is watching. This is that abstraction arriving with a timestamp attached.
There is a harder detail underneath. Aikido reports that because the attacker pushed to main and immediately cut a release through the normal pipeline, the poisoned versions were published to npm with valid provenance signed by GitHub Actions. Build provenance did what it says on the tin — it faithfully attested that this artifact came from that repository via that workflow. It just could not know the repository had been turned. That is the same lesson as the npm worm that walked through SLSA in May, and it is worth being blunt about: provenance proves origin, not intent.
The Case That This Is Overblown
The strongest counterargument is that the industry already shipped the fix, and it is a serious argument that happens to prove the opposite point.
npm v12 went generally available on 8 July 2026 and turned off install scripts by default. GitHub's changelog set out the change: allowScripts defaults to off, blocking preinstall, install and postinstall from dependencies — plus prepare from git, file and link dependencies — unless a project explicitly allowlists them via npm approve-scripts, with --allow-git and --allow-remote also defaulting to none. That is a genuine, structural fix to the class of attack that has dominated the last year, and Microsoft's remediation guidance leads with upgrading the CLI. A team on npm 12 with an empty allowlist was never going to execute setup.mjs at install time.
Good. Now notice that ChainDrop's config-file route does not go anywhere near npm. It does not need an install script, a lockfile entry or a registry. It needs a developer to open a folder.
VS Code makes the same argument more narrowly and more honestly. Workspace Trust blocks task execution in Restricted Mode, and automatic tasks "never run in an untrusted workspace". That is a real mitigation — for a repository you have never opened. It does nothing for the far more common case: a repo your team already trusted months ago, into which a spoofed chore: update config commit later arrives on a routine git pull. Trust is granted per folder and it persists. The content it was granted over does not.
And the agent side of this has already produced a CVE. CVE-2026-48124, rated CVSS 8.5 and published on 19 June 2026, covers Cursor Desktop executing workspace-defined Claude hook commands from .claude/settings.local.json without dedicated user approval; it is fixed in Cursor 3.0.0. Pillar Security, which found it, described the root cause precisely: workspace-sourced hook configuration was treated as project state rather than as execution state. ChainDrop is that same category error, weaponised at registry scale seven weeks later.
The Controls That Already Exist and Nobody Turned On
The good news is that you do not need a new product for most of this. You need three settings and one policy change.
Managed hooks. Anthropic ships a managed-settings tier that outranks project and user configuration. allowManagedHooksOnly blocks user, project and non-force-enabled plugin hooks outright, so only hooks your platform team ships can load. Its sibling allowManagedPermissionRulesOnly stops project files from defining allow/ask/deny rules at all. These live in managed-settings.json under /etc/claude-code/ on Linux and WSL, /Library/Application Support/ClaudeCode/ on macOS, and C:\Program Files\ClaudeCode\ on Windows, and can be pushed by MDM. If your developers run agents against company repositories and you have not deployed a managed settings file, project configuration is currently executing on your endpoints on your behalf.
CODEOWNERS. .claude/, .cursor/, .vscode/, .github/workflows/ and .devcontainer/ should all require review from a named owner. A pull request that touches only a config directory is exactly the pull request that gets rubber-stamped, which is why it needs a rule rather than a habit.
Detection you can run today. Zero Hunt's hunting query is one line and works across your whole estate:
git log --all --diff-filter=A -- '.claude/settings.json' '.vscode/tasks.json'
Run it for every branch, not just main — Elastic's finding was up to 50 branches per repository, and nobody opens branch 47.
What to Do About It
This Week:
- Run the
git log --all --diff-filter=Aquery above across every repository your developers open with an agent, including branches. Treat any addition of.claude/settings.jsonor.vscode/tasks.jsondated on or after 4 August as an incident until proven otherwise, and pay particular attention to commits authored asclaude,github-actions[bot]or anything ending@users.noreply.github.com. - Add the five AI credential paths to your rotation runbook by name —
.claude/credentials.json,.codex/auth.json,.cursor/credentials.json,.openai/auth.json,.anthropic/auth.json— and rotate them from a clean host, in that order, alongside the npm and GitHub tokens you already did. - Check your Cursor version. Anything below 3.0.0 carries CVE-2026-48124.
- Purge CI caches and rebuild golden runner images. A poisoned tarball in a shared cache reinfects every build after it, and this is the step teams skip because the dashboard already went green.
This Month:
- Deploy a Claude Code managed settings file with
allowManagedHooksOnlyset, via the same MDM channel you use for everything else. Decide deliberately whether platform-shipped hooks are an exception; the default should be that repository configuration cannot execute. - Put
.claude/,.cursor/,.vscode/and.devcontainer/under CODEOWNERS with a security or platform reviewer, and make that rule enforced rather than advisory. - Add those directories to your EDR file-integrity monitoring and to whatever your SCA tool ignores today. Ask your vendor directly whether their scanner reads agent configuration files. The answer for most is no, and it is better to know that in a procurement conversation than in an incident.
- Bring the agent keys into your identity inventory the same way you brought service accounts in. If you cannot answer "how many active Claude, Cursor and Codex credentials exist against our org and who holds them," that is the project.
Before Your Next Audit:
- Move to npm 12 with an explicit
approve-scriptsallowlist and a minimum release age, and write down which packages you allowlisted and why. This is a real fix; it just is not this fix. - Rewrite the definition of "developer endpoint" in your asset policy to include the agent configuration directories. Every control gap in this incident traces back to a scope boundary drawn before agents existed.
The Bottom Line
We have been treating AI coding agents as tools and their configuration as preferences. ChainDrop is the demonstration that agent configuration is executable code with a trigger, distributed through git, running with developer privileges, in a directory that no scanner in your stack was built to read. That is not a new attack technique. It is a new place to put an old one, and it arrived at a moment when AI coding assistants are close to universal in large engineering organisations while governance over them is not: 97% adoption against 30% with full governance, in a survey of 831 engineers at companies with 500-plus employees, fielded in March 2026 by UserEvidence for Black Duck — a vendor that sells software supply chain security, and a sample skewed toward technology and SaaS.
The uncomfortable part is how ordinary the fix is. Review the config files. Rotate the keys you forgot were keys. Turn on the managed setting the vendor already shipped. None of it is hard. All of it is currently nobody's job.
Your lockfile is clean. Check the folder that starts with a dot.
Continue Reading
Security Vendor's npm Package Stole AI Coding Keys
npm Worm Bypassed SLSA: OpenAI, Mistral Source Code Stolen
84% Use AI Coding Tools. Every Sandbox Just Broke.
Agentjacking: AI Agents Hijacked via Fake Bug Reports
Your AI Agents Have Keys to Everything. Nobody's Watching.
One Credential, 195 Breached Companies: The Klue OAuth Attack
