← Real-world cases
Case study

keyv/cacheable npm worm plants Claude Code and VS Code hook files as an AI-agent execution vector

Real-world incident04 Aug 2026🗺️ Tool-Using Agent

A self-propagating npm worm reportedly hijacked the keyv/cacheable maintainer account and trojanized hundreds of package versions with a malicious preinstall hook, and additionally committed Claude Code and VS Code hook files into the source repo so that merely opening a checkout in an AI-enabled IDE runs the payload with no npm install.

Root cause — why it happened

Developers install open-source packages by the millions and trust that a popular, long-established one is safe. Attackers stole the account of the person who maintains a very widely used set of npm packages and quietly poisoned hundreds of versions. Two traps were laid. The first is old: a package can run a little script the moment you install it. The second is new: the attacker also slipped in the small setup files that AI coding assistants automatically run when you simply OPEN the project — so you didn't even have to install anything. Security scanners look at the package's install scripts; almost none look at an AI assistant's hidden setup files, so the trap sat in a place nobody checks.

Risks this case illustrates

Named in the standard (OWASP/ATLAS/NIST) lens. Click a highlighted component in the diagram below to see which risks attach where.

How it unfolded

UntrustedAgent coreOversightThe real worldgoalif allowed🧑User🎛️Orchestrator /Agent Loop🧠LLM🔐Identity &Permissions🔧Tool RuntimeHuman ApprovalGate🔌External APIs🗄️BusinessDatabase🌐UntrustedContent📝Audit Logging🌐Trojanizeddependency🖥️Developer host+ AI-IDE hook
InstructionsDataActionsControl / decisionFeedback / logscrosses a trust boundary
👆 Click a component or flow to inspect
SetupStep 1 / 7

A developer working inside an AI-enabled IDE

A developer uses an AI coding assistant built into their editor. As a convenience, the assistant automatically runs a project's small setup hooks when the project is opened, so it's ready to help right away. That auto-run convenience is what everyone is trusting to be harmless.

Step 1 / 7

Controls & guardrails — what would have stopped it

The trap needed two things: a poisoned package to reach the developer, and an AI assistant willing to run the package's setup files automatically. Break either. Verify where each package version really came from so the poisoned ones are caught, and don't let the AI assistant auto-run setup files that arrived inside a downloaded project without a person approving. Then run installs in a locked box and give build logins only tiny, short-lived powers — so even a payload that runs steals little and can't spread.

Preventive
Detective
  • Runtime monitoring & anomaly detection

    Detects the anomalous, not the novel-but-subtle; high false-positive rates cause alert fatigue. Always a step behind a sufficiently quiet attacker.

  • Full-trace audit logging

    Logging is forensic, not preventive — it explains harm after the fact. Useless if no one reviews it or if the materialised context isn't captured.

Corrective
  • Governance: risk assessment, red-teaming & incident response

    Process reduces likelihood and speeds recovery but executes no technical control itself; weak follow-through makes it theatre.

  • Loop/cost circuit-breakers & consistency checks

    Thresholds are blunt — too tight breaks legitimate long tasks, too loose lets damage accrue first. Catches runaway dynamics, not a single well-formed bad decision.

Lessons

  • AI-agent hook/config files (`.claude`, IDE tasks) are an autorun surface: if an attacker can commit them into a dependency, opening the checkout runs their code — no `npm install` needed.
  • `--ignore-scripts` only governs the npm lifecycle path; it does nothing for the agent-hook path that fires on repo-open, so the two surfaces need separate controls.
  • Dependency scanners and reviewers model `package.json` scripts, not agent config — committed hook files hide malware in a trusted-but-unmonitored location.
  • Trust anchored to a package's name and download count is not provenance; verify each version's origin (lockfiles, integrity hashes, signed releases).
  • Least-privilege, short-lived CI/cloud credentials plus egress control both cap the blast radius and deny a credential-worm the publish rights it needs to spread.

Proposals & gaps this case surfaced

Non-destructive suggestions for the library — proposed, not adopted.

★ proposed sub-riskCode execution via attacker-committed AI-agent hook/config files in a dependencyunder #42

A supply-chain code-execution vector in which an attacker commits AI-agent hook/config files (e.g. Claude Code `.claude` hooks, VS Code task/hook files) into a package or repository, so that a developer's AI-enabled IDE or coding agent auto-executes the payload on repo-open — with the developer's ambient privileges, no `npm install`, and no approval prompt. It is distinct from a poisoned package lifecycle script (`preinstall`/`postinstall`) because it fires outside the package-manager lifecycle, defeating `--ignore-scripts` and install-time sandboxing, and it hides in a path (agent config) that dependency scanners and code review typically do not inspect.

✚ proposed guardrailDeny auto-execution of AI-agent hook/config files (.claude, IDE tasks) from untrusted checkouts, and bring agent config into supply-chain scanning and review scopeAgent Runtime Safety & Containment

Treat every autorun surface an AI coding agent honours as attacker-populatable, and cover both the package lifecycle and the agent-hook path. (1) Do not auto-execute project-scoped agent hook/config files (`.claude/settings*.json` hooks, VS Code tasks) from an untrusted workspace on repo-open — require explicit developer consent, or restrict auto-run to an allowlist of vetted repositories. (2) Bring agent hook/config files into SCA and code-review scope so they are inspected like `package.json` scripts (they are code, not just settings). (3) On the supply-chain side, pin and verify dependency provenance (lockfiles, integrity hashes, signed releases) and install with scripts suppressed (`--ignore-scripts`) inside a sandbox — noting this does NOT cover the repo-open hook path, which needs control (1). (4) Scope CI/cloud credentials to least privilege with short-lived tokens and egress allow-listing, so a payload that does run cannot harvest broadly, move laterally, or reuse publish rights to propagate. Closes the keyv-worm vector where committed agent-hook files execute on checkout-open; distinct from lifecycle-script mitigations, which the agent-hook path bypasses.

This case shows a blind spot: we scan a package's install scripts for malware, but almost nobody scans the AI assistant's setup files — even though the assistant runs them automatically when you open a project. An attacker who hides code in those files gets a free run. Reviews and scanners should read AI-agent config the same way they read install scripts.

These surface as proposals across the Control Library and Risk Taxonomy; adopt them by hand when ready.

Sources

AI RiskAtlas is an educational model of how GenAI & agentic systems work and fail. Architectures and payloads are illustrative and simplified for learning — not operational guidance. Real-world cases are summarised from public reporting.

Sources & further reading →·Built by Shi Yuan ↗