Skip to content

fix(shell): demote destructive flags on allowlisted commands#258

Merged
esengine merged 2 commits into
mainfrom
fix/shell-risky-arg-demotion
May 5, 2026
Merged

fix(shell): demote destructive flags on allowlisted commands#258
esengine merged 2 commits into
mainfrom
fix/shell-risky-arg-demotion

Conversation

@esengine

@esengine esengine commented May 5, 2026

Copy link
Copy Markdown
Owner

Summary

  • Closes git branch -d bypasses review mode #257git branch -D (and similar destructive flags on otherwise-allowlisted commands) skipped review mode because the allowlist match looked at the leading tokens only.
  • Adds a per-prefix RISKY_ARGS table in src/tools/shell.ts. When an allowlisted prefix matches but a tail token is in that prefix's risky list, the call falls back to the confirm gate. Read-only forms (git branch, git branch -v, find -name '*.ts', npx eslint src, …) stay on the fast path.
  • Audited the rest of BUILTIN_ALLOWLIST for the same class of bypass while in there. New rules cover: git branch, git remote, git diff/log/show (--output, --ext-diff), find (-delete, -exec*, -ok*, -fprint*), npx eslint --fix, npx biome check --write/--apply*, ruff --fix/--unsafe-fixes/format.
  • Both --flag value and --flag=value forms are caught, so git diff --output=x.patch and git diff --output x.patch both demote.
  • Chain commands (a && b, a | b) inherit automatically — chainAllowed already calls isAllowed per segment.
  • npm test / pytest / cargo test etc. are intentionally not gated further: the contract of these allowlist entries is "run user code", and no flag-level filter would meaningfully constrain that.

Test plan

  • npm run verify (build + lint + typecheck + 2260 tests, all pass)
  • New risky-arg demotion describe block in tests/shell-tools.test.ts — 5 groups covering each RISKY_ARGS prefix with happy + sad paths, including the --flag=value form
  • Manual repro of the original bug fixed: git branch -D feature/foo now hits the confirm gate instead of executing immediately

esengine added 2 commits May 5, 2026 04:13
Allowlist matched on leading tokens only, so `git branch -D`,
`find -delete`, `git diff --output=...`, `npx eslint --fix`, etc.
flowed through without confirmation. Add a per-prefix RISKY_ARGS
table that demotes specific tail tokens back to the confirm gate;
both `--flag value` and `--flag=value` forms are caught. Chains
inherit via the existing per-segment isAllowed call.
Follow-up audit caught two more write-anywhere paths on otherwise-
allowlisted inspection tools: `tree -o FILE` writes the tree output,
and `find -fprint0 FILE` writes NUL-separated paths. Same risk class
as the `git diff --output=` family already covered.
@esengine esengine merged commit 4e16baa into main May 5, 2026
3 checks passed
@esengine esengine deleted the fix/shell-risky-arg-demotion branch May 5, 2026 11:25
ChasLui pushed a commit to ChasLui/DeepSeek-Reasonix that referenced this pull request May 23, 2026
…e#258)

* fix(shell): demote destructive flags on allowlisted commands (esengine#257)

Allowlist matched on leading tokens only, so `git branch -D`,
`find -delete`, `git diff --output=...`, `npx eslint --fix`, etc.
flowed through without confirmation. Add a per-prefix RISKY_ARGS
table that demotes specific tail tokens back to the confirm gate;
both `--flag value` and `--flag=value` forms are caught. Chains
inherit via the existing per-segment isAllowed call.

* fix(shell): also demote tree -o and find -fprint0 (esengine#257)

Follow-up audit caught two more write-anywhere paths on otherwise-
allowlisted inspection tools: `tree -o FILE` writes the tree output,
and `find -fprint0 FILE` writes NUL-separated paths. Same risk class
as the `git diff --output=` family already covered.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

git branch -d bypasses review mode

1 participant