How to stop an AI coding assistant from installing vulnerable packages

You hand Claude Code a real job — “add image uploads to this app, resize them, store them in S3” — and let it work. It writes the code, realises it needs a few libraries, and installs them itself: a pip install here, an npm install there, perhaps a brew install for some system tool. You are following the plan, not reading package names as they fly past. And every one of those installs runs with your user account, your file access, your credentials. The assistant is fast and genuinely helpful — and, for those few seconds, it is also the thing deciding what new code gets to run on your machine.

Claude Code does not check whether the packages it installs have known security problems; that was never part of its job. Usually it reaches for something popular and perfectly fine. But it has no way of knowing whether the version it just grabbed went live an hour ago, or whether something three dependencies deep was quietly compromised last night. When the installer is an AI moving quickly across several different package ecosystems in one session, the blast radius of a single bad pick is exactly the size of your own access — which is to say, all of it.

claude-code-cve-gate sits in front of that moment. It is a hook that intercepts every install your assistant tries to run — across pip, npm, composer, cargo, go, gem and brew — checks it before it executes, and stops the ones that come back dirty.

The problem, in plain terms

A human installing a package at least sees the name and can pause on something unfamiliar. An autonomous assistant does not pause, and you are usually reviewing its intent (“add uploads”), not its shopping list (“installed sharp, multer, and 40 transitive dependencies”). Multiply that by the number of ecosystems a modern agent reaches into — Python, Node, system packages — and you have several open doors, each one trusting that whatever comes through is fine. Nothing in the default setup is checking.

Who runs into this

Anyone who lets an AI coding assistant run installs rather than copying commands out to run by hand — which is the entire point of an agentic workflow. The more you trust the assistant to act, the more this gap matters, because “trust it to act” includes “trust whatever it installs.”

What claude-code-cve-gate does — and how it works

It registers as a PreToolUse hook — Claude Code’s documented extension point that fires before a command runs. The gate inspects each install the assistant attempts and decides whether to let it through.

How claude-code-cve-gate screens an AI's installAn install the AI assistant runs is intercepted by a PreToolUse hook, which resolves and checks the dependency tree before anything executes, blocking a vulnerable one.AI installspip · npm · brew …PreToolUse gatechecks the treebefore it runsBlockedbefore code runs
The hook intercepts every install the assistant runs and checks it before any code executes — with your access on the line.

It intercepts the install before it runs

When Claude Code reaches for pip, npm, composer, cargo, go, gem or brew, the hook catches the command first — nothing is downloaded or executed until the check has had its say.

It resolves the whole dependency tree

For pip, npm, composer and gem, the gate uses each package manager’s own dry-run mode to resolve the full transitive tree, so indirect dependencies are screened, not just the package the assistant named. (--no-deps limits the check to the top level when you want that.)

Three databases and a freshness hold

Every resolved package is checked against NIST NVD, OSV.dev and the GitHub Advisory Database, with version-aware filtering. For pip and npm it also applies a freshness hold — a release younger than three days (by default) is held, since the most dangerous version is often the one published minutes after a credential theft. Override it for a single session with SAFE_INSTALL_MIN_AGE=0 when you genuinely need a just-released fix.

Honest defaults, and a strict mode

By default the gate is best-effort: if at least one database returns a clean verdict it allows the install, so a single unreachable feed does not block your work. When you want the stricter posture — any database error becomes a hard block — set STRICT_FAIL_CLOSED=1. It is worth knowing which mode you are in, so the gate is explicit about it rather than pretending every check is absolute.

Install & use it

Install

git clone https://github.com/sharkyger/claude-code-cve-gate.git
cd claude-code-cve-gate && bash install.sh

install.sh registers the PreToolUse hook in your Claude Code configuration.

After that, it just works

There is nothing to run. Once the hook is registered, every install Claude Code attempts is screened automatically; a clean one proceeds, a vulnerable one is blocked and reported. Tune the freshness hold or strict mode through the environment variables above. Full configuration and source are on GitHub: github.com/sharkyger/claude-code-cve-gate (MIT).

FAQ

Does Claude Code check packages before installing them?

No — Claude Code can install packages for you but does not screen them for known vulnerabilities. claude-code-cve-gate adds that check as a hook: it intercepts each install your assistant runs and screens it before it touches your system.

Which package managers does it cover?

pip, npm, composer, cargo, go, gem and brew. For pip, npm, composer and gem it resolves the full transitive dependency tree via the package manager’s own dry-run mode, so indirect dependencies are checked too.

Is this an official Anthropic tool?

No. claude-code-cve-gate is an independent, third-party tool and is not affiliated with Anthropic. It hooks into Claude Code’s documented PreToolUse extension point.


claude-code-cve-gate is one of the 5bats supply-chain gates. If your stack is built on Mistral instead, mistral-code-cve-gate does the same for it; for installs you run yourself there are gates for Python, PHP and Homebrew.

See the source and setup on GitHub →