SyndaiSign inStart free
← Back to blog

The npm worm that plants itself in your coding agent's config

·Syndai Team·5 minutes
ai-agents
security
coding-agents
supply-chain

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. 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.
  • 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.

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.