Malware Found a New Home: Your AI Coding Agent's Hooks
TechCurrent Staff•05:17 UTC•6 min read

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. Supply-chain worms are no longer news on npm. What makes this one worth your attention is where it chose to live: inside 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.
That design decision says something about where malware authors think developer machines are going, and it deserves a plain-language explanation that the incident-response write-ups were not built to give.
How agent hooks actually work
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 that is 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.
So the trust gates exist. The problem is when they fire. You granted trust to that repository months ago, back when it deserved it. The malicious commit arrived last night, through a compromised dependency. On your next session start there is no new prompt, because the folder is already trusted. The trust decision is made once, long before the malicious commit exists.
Security firm StepSecurity, whose analysis contains 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", camouflaged as routine AI-agent activity in a repository where AI-authored commits are normal.
Why do attackers want hooks at all, when npm's install scripts already give them code execution? 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, in a dot-directory most teams never diff-review. Persistence used to require effort. In an agent-tooling world it is a JSON edit.
What it came for
The stealer's shopping list is the second signal of where things are heading. According to Wiz, alongside the classic targets (cloud credentials, CI/CD secrets, crypto keystores) it harvested 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`.
AI credentials are worth stealing for the obvious resale reasons, but MCP configuration is the more interesting target: it describes which external systems your agent is wired into, and may carry the tokens that reach them.
A command channel you cannot sinkhole
The third notable choice is how the malware found its command-and-control servers. Instead of a hardcoded domain that defenders could seize or block, it read the current list of C2 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. And 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.
This pattern (sometimes called EtherHiding, or a dead-drop resolver) resists the standard takedown playbook for a simple reason: 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.
The lineage, briefly
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 operating 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 25 | Attacker registers C2 domains and deploys the Ethereum resolver contract (Unit 42) |
| Aug 4, ~09:00 | First malicious commits in the keyv repository (Wiz, Datadog) |
| Aug 4, 09:35 | keyv 6.0.0 published to npm; automated republishing spreads to 400+ packages within hours |
| Aug 4, 13:45 | Wiz publishes its initial analysis |
| Aug 4, 15:15 | One 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 uncomfortable takeaway is not that hooks are dangerous. It is that your agent tooling is now part of your attack surface, and almost nobody is reviewing it like code.
The fix is cultural as much as technical. Dot-directories used to be inert preference files, and team review habits still assume they are. This campaign is the clearest evidence yet that the assumption has expired.
“The trust decision is made once, long before the malicious commit exists.”
Reporting by TechCurrent Staff · TechCurrent
