TechCurrent
Breaking
DDR4 Costs 60% More Than DDR5 on One Board of FiveRSA-260 Falls to 4,900 GPU-Days and a Coding AgentDangote's IPO Broke Three Nigerian Investing Apps at LoginGitHub's Copilot Cost Dial Spans 14 Models Priced 25x ApartMost AI Coding Tools Fix Security Bugs Without AdvisoriesShopify Left React Native. The CLI Is the Reusable Part.
AI

ChainDrop npm Worm Hid in Claude Code and VS Code Configs

TechCurrent Staff•Sep 3•5 min read

ChainDrop npm Worm Hid in Claude Code and VS Code Configs
ChainDrop npm Worm Hid in Claude Code and VS Code Configs · illustration: TechCurrent.
Share:

On August 4, an attacker who had taken over the npm account behind the popular keyv and cacheable caching libraries pushed trojanized versions of more than 400 packages, according to analyses published by Wiz and Palo Alto Networks Unit 42, which named the campaign ChainDrop. npm has absorbed supply-chain worms before. The new part is where this one set up house: the configuration files of AI coding tools.

The worm planted a matched pair of auto-run entries in repositories it could reach. One was a Claude Code hook in `.claude/settings.json`, set to fire whenever a coding session starts. The other was a VS Code task in `.vscode/tasks.json`, set to fire whenever the folder opens. Each entry launched a dropper hidden in the other tool's directory, so opening the project in either tool re-infected the machine, and a developer who checked one dot-directory and found nothing suspicious would miss the other half of the pair.

The trust prompt comes months before the attack

Hooks are a legitimate, documented feature. Claude Code lets you register shell commands that run on lifecycle events (session start, before and after tool calls, and so on), and project-level hooks live in `.claude/settings.json`, a file designed to be committed and shared with your team. VS Code has an equivalent in tasks marked `runOn: folderOpen`. According to the official Claude Code documentation, project hooks only run after you accept the workspace trust prompt for that folder, and VS Code will not run folder-open tasks in an untrusted workspace at all.

The catch is timing. You granted trust to that repository months ago, back when it deserved it. The malicious commit arrived last night, through a compromised dependency, and your next session start produces no new prompt because the folder is already trusted. The trust decision is made once, long before the malicious commit exists.

StepSecurity, whose analysis has the most granular file-level detail, reported that the worm committed its hook files across every branch it could reach, with the commits authored as "claude". In a repository where AI-authored commits are normal, that reads as routine agent activity.

Attackers already get code execution from npm's install scripts, so why bother with hooks? Our reading of the vendor analyses: an install script runs once, at install time. A session hook runs every time you sit down to work, with your full developer privileges, on a machine that holds cloud keys, npm tokens and now AI API keys, and it lives in a dot-directory most teams never diff-review. Persistence used to take real work; here it is a JSON edit.

What it came for

According to Wiz, the stealer went after the classic targets (cloud credentials, CI/CD secrets, crypto keystores) and kept going, harvesting the credential and configuration stores of AI tools: Claude, OpenAI and Codex, Cursor, and Gemini, plus MCP server configuration files. StepSecurity's more detailed list names paths like `.claude/credentials.json`, `.cursor/credentials.json` and `.kiro/settings/mcp.json`.

Stolen AI keys have obvious resale value. MCP configuration is arguably the better haul, because it describes which external systems your agent is wired into and may carry the tokens that reach them.

A command channel you cannot sinkhole

Instead of a hardcoded domain that defenders could seize or block, the malware read its current list of command-and-control domains from a smart contract on the Ethereum mainnet, trying public RPC endpoints (dozens of them, per Unit 42) until one answered.

According to Unit 42, the infrastructure was prepared months ahead: domains registered in May within seconds of each other, the resolver contract deployed days later. When defenders started blocking the initial domains on August 4, a single on-chain transaction rotated the entire list to fresh infrastructure in under an hour, with no malware update required.

The pattern is sometimes called EtherHiding, or a dead-drop resolver, and it resists the standard takedown playbook because there is no domain to sinkhole at the lookup layer. Reads from a public blockchain are free, anonymous and reachable through dozens of interchangeable providers, and nobody can edit or delete someone else's deployed contract. Defenders can and did block the exfiltration domains themselves; the pointer to the next set stays up indefinitely.

Shai-Hulud's toolkit, in unknown hands

Wiz identifies the payload as a descendant of the Shai-Hulud worm family that hit npm in September 2025 and again, at much larger scale, that November. The toolkit has since circulated publicly. Unit 42 is explicit that the technical fingerprints match but that it cannot yet say whether the original group is running this wave or a copycat is remixing the published tooling. Nobody has established how the maintainer's account was compromised in the first place, and no vendor has named an actor. Treat attribution here as an open question, because the primary sources do.

The timeline

Date (UTC, 2026)Event
May 11 to 25Attacker registers C2 domains and deploys the Ethereum resolver contract (Unit 42)
Aug 4, ~09:00First malicious commits in the keyv repository (Wiz, Datadog)
Aug 4, 09:35keyv 6.0.0 published to npm; automated republishing spreads to 400+ packages within hours
Aug 4, 13:45Wiz publishes its initial analysis
Aug 4, 15:15One on-chain transaction rotates the C2 domain list

Ten minutes of hardening

Everything below comes from the vendor guidance and the tools' own documentation.

- Treat `.claude/`, `.vscode/`, `.cursor/` and `.mcp.json` as executable code in review. Diff them like source. A hook in one tool's config that points at a script in another tool's directory is the tell from this campaign. - Audit what is already registered: Claude Code's `/hooks` menu lists every active hook and where it came from; check `.vscode/tasks.json` for `runOn: folderOpen`. - Leave VS Code's `task.allowAutomaticTasks` off (the default), and remember that workspace trust, once granted, persists across every future pull. - Teams can go further: Claude Code ships enterprise settings to disable hooks entirely or restrict execution to admin-managed hooks. - Standard npm hygiene still matters, because it was the delivery vehicle: `ignore-scripts` in CI where feasible, lockfiles, and a cooldown before adopting brand-new versions of anything. - Keep long-lived API keys out of AI tool config files where you can, and if you installed an affected version, treat the machine as compromised: rebuild, remove the planted hook files, and rotate every credential class, which is the explicit recommendation from both Wiz and Unit 42.

The hooks themselves worked exactly as documented. What changed underneath them is the dot-directory: for years it held editor preferences and linter settings, and code review habits formed around the assumption that nothing in there runs. That assumption is where ChainDrop lived.

“The trust decision is made once, long before the malicious commit exists.”
Advertisementtc-article-infeed

Reporting by TechCurrent Staff · TechCurrent

Stay Ahead of the Curve

Get the daily brief on AI, hardware, and the future of tech. Directly to your inbox.