Gap
The bash tool already gates global package installs (npm install -g, pnpm add -g, yarn global add, pip install --user, cargo install, go install). But project-local installs, npm install <pkg>, npm i, yarn/pnpm/bun add, and npx/bunx/pnpm dlx runners, run after a generic "Execute command" prompt that gives no signal about what is being pulled in. A single mistyped name (npm install lodahs instead of lodash) is a classic supply-chain attack.
Proposal
An offline, deterministic check that parses npm/yarn/pnpm/bun install and runner commands out of the shell command and flags any target package whose name is exactly one edit from a curated popular package. On a hit it enriches the existing permission.Request prompt (for example: "Install suspected typosquat: lodahs, did you mean lodash?") so the human can verify before allowing. It never hard-denies on its own (unlike the existing global-install BlockFuncs) and adds no dependencies.
Design:
- Pure/offline/deterministic. Gate: Optimal String Alignment (restricted Damerau-Levenshtein) distance == 1 and popular name length > 4.
- Hardening: sub-command splitting (
;/&&/||/|/&/newlines), env-assignment + wrapper prefixes (sudo, env ...), quote stripping, global-option skip, value-flag skip (so npm install --prefix axio lodash does not false-flag axio), @scope/pkg@version normalization.
It sits next to the existing install-gating in internal/agent/tools/bash.go and routes through permission.Request rather than a hard-deny BlockFunc, so the human stays in control. I have a working implementation + table tests ready (go test, go vet, gofmt clean) and proposed the same check upstream in Goose: aaif-goose/goose#9642. Happy to open the PR (I'll sign the CLA).
Gap
The bash tool already gates global package installs (
npm install -g,pnpm add -g,yarn global add,pip install --user,cargo install,go install). But project-local installs,npm install <pkg>,npm i,yarn/pnpm/bun add, andnpx/bunx/pnpm dlxrunners, run after a generic "Execute command" prompt that gives no signal about what is being pulled in. A single mistyped name (npm install lodahsinstead oflodash) is a classic supply-chain attack.Proposal
An offline, deterministic check that parses npm/yarn/pnpm/bun install and runner commands out of the shell command and flags any target package whose name is exactly one edit from a curated popular package. On a hit it enriches the existing
permission.Requestprompt (for example: "Install suspected typosquat:lodahs, did you meanlodash?") so the human can verify before allowing. It never hard-denies on its own (unlike the existing global-installBlockFuncs) and adds no dependencies.Design:
;/&&/||/|/&/newlines), env-assignment + wrapper prefixes (sudo,env ...), quote stripping, global-option skip, value-flag skip (sonpm install --prefix axio lodashdoes not false-flagaxio),@scope/pkg@versionnormalization.It sits next to the existing install-gating in
internal/agent/tools/bash.goand routes throughpermission.Requestrather than a hard-denyBlockFunc, so the human stays in control. I have a working implementation + table tests ready (go test,go vet,gofmtclean) and proposed the same check upstream in Goose: aaif-goose/goose#9642. Happy to open the PR (I'll sign the CLA).