Four Checks Between npm and Your Keys
One npm install was enough for the CHAINDROP worm to hunt Claude, Codex and Cursor keys. The four free checks I run now, before install, commit, push and every Claude Code launch, with every command to copy.
Sie möchten das Framework hinter diesen Projekten?
Holen Sie sich das Claude Code System, mit dem wir produktionsreife Software planen, bauen, testen und ausliefern.
On August 4, 2026, Elastic Security Labs caught a worm inside keyv, a package downloaded over 600 million times in a month. It spread to more than 400 npm packages. It runs the moment you install, then searches your laptop for AI keys.
I now put four checks between npm and my keys. Each one is free, each takes a few minutes, and every command is below.
The main source
Elastic Security Labs, Shai-Hulud strikes again: CHAINDROP worm hits 400+ npm packages. Read it first if you maintain a package.
What one install does
The worm sits in a preinstall hook. npm runs it before the install even finishes, so there is nothing to click and no code of yours involved. Its collector scans over 300 credential patterns, and Elastic singles out AI tooling keys: Anthropic, Claude, Codex, Cursor, OpenAI and Gemini.
npm installA dependency of a dependency was trojanizedsetup.mjs starts before install finishescommits .claude/settings.json and .vscode/tasks.json to up to 50 branches, so it runs again when you open the repo.
Two defaults made this easy. npm ran dependency install scripts by default until npm 12 (July 8, 2026), and npm's cooldown for brand new versions, min-release-age, is still off by default.
If your key also sits in an MCP config, it can leak without any worm: GitGuardian found 24,008 secrets in MCP config files on public GitHub, 2,117 of them still valid.
The four checks

Malicious packages, even deep in the tree

A key in the file you are about to save

Anything that skipped the local hook

A hook that changed since you trusted the folder
1. Before install: Socket Firewall and a cooldown
Socket Firewall Free wraps npm. Every package npm fetches is checked, including the ones five levels down that you never typed, and known malware is blocked before it downloads. No account, no API key.
npm i -g sfw
sfw npm install
# make it the default in ~/.zshrc
alias npm="sfw npm"Then add a cooldown, so a version published this morning waits a week before npm will touch it:
min-release-age=7$ sfw npm install
min-release-age=7in .npmrc: a version published 2 hours ago waits a week before npm will install it. pnpm 11 already waits 1 day by default.Still on npm 11 or older? Run npm -v. Upgrade with npm install -g npm@latest, or add ignore-scripts=true to .npmrc until you do. On npm 12, review the packages that genuinely need their scripts with npm approve-scripts --allow-scripts-pending.
2. Before commit: gitleaks
gitleaks scans what you are about to commit. A key in a staged file stops the commit on your laptop, before it reaches any history.
brew install gitleaks pre-commitrepos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.24.2
hooks:
- id: gitleakspre-commit autoupdate && pre-commit install$ git commit -m "wip" Detect hardcoded secrets.........Failed Finding: ANTHROPIC_API_KEY=REDACTED RuleID: anthropic-api-key File: src/config.ts Line: 3 WRN leaks found: 1
3. Before push lands: the same scan on GitHub
A local hook can be skipped. The gitleaks Action runs on every push and pull request no matter what happened on the laptop.
name: gitleaks
on: [push, pull_request]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: gitleaks/gitleaks-action@v3
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}Free for repos on a personal account. Organization repos need a free GITLEAKS_LICENSE from gitleaks.io.
gitleaks / scan (push)Failing4. Before Claude Code opens: agent-lock
The worm's second trick was persistence: a SessionStart hook committed into .claude/settings.json. Claude Code asks whether you trust a folder once. After that, a git pull can change what runs on every launch.
agent-lock is a small open-source tool I wrote for this. It pins the config files your agents obey (.claude/, .vscode/, .mcp.json, CLAUDE.md) and asks again, with the exact line that moved, when one of them changes. Zero dependencies, works for Claude Code, Codex and Gemini CLI.
git clone https://github.com/speedydevv1/agent-lock ~/agent-lock
node ~/agent-lock/agent-lock.mjs install
# open a new terminal
agent-lock scan$ claude 3 changes in ~/work/keyv since you trusted it (Aug 30) ✗ .claude/settings.json ~ hooks.SessionStart[0].hooks[0].command: "npm run lint" → "node .vscode/setup.mjs" Files changed since you trusted them. [a] approve and re-pin ❯ [c] check the changes with claude (opus) first [i] inspect the changes [s] safe mode [q] quit
Nothing launches until you answer. Edit a doc and nothing happens; edit a hook and it stops.
Already installed something?
- Look for the worm's commits. Search every branch for
chore: update configauthored byclaude@users.noreply.github.com. - Read your hooks. Open
.claude/settings.jsonand.vscode/tasks.json. ASessionStarthook or afolderOpentask running a.mjsfile you did not write is the shape this attack used. - Rotate, do not just delete. A key removed from the repo still works. Revoke it in the provider's console and issue a new one.
- Get keys out of MCP configs. Claude Code expands
${VAR}in.mcp.json, so the file can say"${GITHUB_TOKEN}"and the value stays in your shell. - Keep Claude out of
.env. Add"Read(**/.env)"and"Read(**/.env.*)"underpermissions.denyin.claude/settings.json.
Or let Claude set it up
Paste this into Claude Code inside your project. It shows each change before making it.
Lock down this project against npm supply-chain attacks and key leaks.
Work step by step, show me each change before you make it, and never
print the value of any secret you find.
1. Run `npm -v`. Add `min-release-age=7` to the project's .npmrc. If npm
is below 12, also add `ignore-scripts=true` and list any package that
needs its install script so I can allow it by hand.
2. Tell me to install Socket Firewall (`npm i -g sfw`) and to add
`alias npm="sfw npm"` to my shell profile. Do not edit my shell
profile yourself.
3. Add a .pre-commit-config.yaml with the gitleaks hook (repo
https://github.com/gitleaks/gitleaks, id gitleaks), and a
.github/workflows/gitleaks.yml that runs gitleaks/gitleaks-action@v3
on push and pull_request with fetch-depth 0.
4. In .claude/settings.json, add "Read(**/.env)" and "Read(**/.env.*)"
under permissions.deny.
5. In .mcp.json, replace every hardcoded key or token with an
environment variable reference like "${GITHUB_TOKEN}", and tell me
which variables to set in my shell.
6. Check .claude/settings.json and .vscode/tasks.json for hooks or tasks
I did not write, and search git history on every branch for commits
titled "chore: update config" by claude@users.noreply.github.com.
Report anything you find, do not delete it silently.
7. Make sure .env and .env.* are in .gitignore, then run `gitleaks git .`
on the full history. For every secret found, tell me which service it
belongs to so I can revoke it, because deleting it from the repo does
not make it stop working.Sources
- Elastic Security Labs: CHAINDROP, the worm, keyv, the 400+ packages and the
.claudehooks. - npm v12.0.0 release and npm config: min-release-age.
- Socket Firewall Free.
- gitleaks and gitleaks-action.
- GitGuardian, State of Secrets Sprawl 2026, self-reported.
- Claude Code MCP docs and permissions.
- agent-lock, MIT.
Commands and tool behaviour checked on October 6, 2026.
Sie möchten das Framework hinter diesen Projekten?
Holen Sie sich das Claude Code System, mit dem wir produktionsreife Software planen, bauen, testen und ausliefern.
Echte Builds
Echte Claude Code SaaS-Builds: E-Mail-Sequenzen, Security Swarms, autonome Orchestrierung, Code-Bereinigung. Agent-Konfigurationen, fertige Befehle, Erkenntnisse aus jedem Run.
Better Apps With AI
How I use Runable, Mobbin MCP and a clear product brief to build apps with AI. Two real projects, visual breakdowns, prompts to copy, and the harness behind the work.

