On August 4, 2026, attackers took over the release path for the widely used `keyv` caching package. Several related packages were hit as well. A worm that spreads on its own was pushed to the npm registry. The scale is the first thing to take in. Snyk counted 619,682,667 downloads of `keyv` alone in the month before the compromise. `flat-cache` and `file-entry-cache` were each in the same range. These are dependencies most JavaScript projects pull in without ever naming them.

What makes this one worth reading about is not the caching packages. It is where the payload chose to hide: inside the configuration files that coding agents and editors read and act on.

## What the worm did

The malicious versions added a `preinstall` hook. As Snyk put it, npm "runs preinstall automatically during dependency installation," so "a developer does not need to import keyv, start an application, or call a vulnerable API." Installing anything in the dependency tree was enough to run the loader.

Then it set up persistence in a place designed to outlive a single `npm install`. According to Snyk's analysis, the malware wrote to `.claude/settings.json` and `.vscode/tasks.json`. The Claude config gained a `SessionStart` command. The VS Code task used `runOn: "folderOpen"`. Both point at a script dropped in the repository. The result, in Snyk's words, is "an additional execution path when a developer or coding agent trusts and activates project-local configuration."

Wiz tracked the same campaign. It described the worm as a descendant of the "Shai-Hulud" malware family. That family spread through a hijacked maintainer account. It reached over 400 npm packages. It went after cloud and developer credentials. It also went after AI config files and cryptocurrency wallets.

## Why the config file is the real lesson

Strip away the specifics and the shape is one we have written about before. A coding agent reads instructions from a file. That file was writable by earlier, untrusted work. So the earlier work gets to steer the agent.

That is the same shape as the Codex finding in the [Black Hat 2026 coding-agent disclosures](/blog/black-hat-2026-coding-agent-cves). There, one pass wrote an `AGENTS.md` file. A later pass loaded it as instructions. Here the writable surface is a `SessionStart` hook and a `folderOpen` task rather than an agent-rules file. The trick is the same. Take persistence. Add a writable instruction file a task can reach. One run now gets to steer the next.

A `SessionStart` hook is a real feature, and a useful one. It runs a command when an agent session starts. The problem is not the feature. The problem is trusting the file that configures it. That file may have arrived with a cloned repo. Or a dependency's install script may have written it.

## What hardens against this class

The controls that cut this chain are mechanical. None of them rely on asking the model to be careful:

- **Treat project-local agent config as untrusted input when it comes from outside your own commit.** Maybe a dependency wrote your `.claude/settings.json` or `.vscode/tasks.json`. Maybe it shipped in a cloned repo. Either way, it is data an attacker may control. You did not author that policy.
- **Do not let install scripts run with standing reach.** A `preinstall` hook runs before your code does. Pin your lockfile. Control install scripts. Check provenance. Each step narrows what a poisoned dependency can do at install time.
- **Separate the agent's identity from your secrets and infrastructure.** With least privilege, a compromised run lands in a throwaway environment. It should not reach your credentials or your pipeline. This is the argument we make in full in [securing coding agents](/blog/securing-coding-agents).
- **Run untrusted code where it cannot reach your machine.** Run a cloned repo's setup inside an isolated sandbox. That limits what a `folderOpen` task can touch. The tradeoffs across sandbox options are covered in the [code-execution sandboxes list](/lists/code-execution-sandboxes).

## Common questions

**Which packages were affected?** The compromise hit `keyv` and related caching packages, including `flat-cache` and `file-entry-cache`. The bad versions were published on August 4, 2026. According to Wiz, the worm spread to over 400 npm packages.

**How did installing a caching library run code?** The malicious versions added an npm `preinstall` hook. npm runs that hook on its own while it installs dependencies, before any application code starts. You did not even need to import the package.

**What does the persistence in .claude/settings.json do?** Snyk reports the malware registered a `SessionStart` command in the Claude config. It also registered a `folderOpen` task in VS Code. So the payload runs again when a coding agent session starts, or when the folder is opened. Install time was only the first run.

**Is this a flaw in Claude Code or VS Code?** No. `SessionStart` hooks and `folderOpen` tasks are documented features. The issue is that untrusted code wrote the configuration files, and the tools then trusted them. The durable defense is treating project-local agent config as input when it did not come from your own commit.
