docs: align safe-bin denied flag list

This commit is contained in:
Peter Steinberger
2026-04-23 18:25:18 +01:00
parent 8f3b99c512
commit b3d32a995d

View File

@@ -316,61 +316,61 @@ so file operands cannot be smuggled as ambiguous positionals.
[//]: # "SAFE_BIN_DENIED_FLAGS:START"
- `grep`: `--dereference-recursive`, `--directories`, `--exclude-from`, `--file`, `--recursive`, `-R`, `-d`, `-f`, `-r`
- `jq`: `--argfile`, `--from-file`, `--library-path`, `--rawfile`, `--slurpfile`, `-L`, `-f`
- `sort`: `--compress-program`, `--files0-from`, `--output`, `--random-source`, `--temporary-directory`, `-T`, `-o`
- `wc`: `--files0-from`
- `grep`: `--dereference-recursive`, `--directories`, `--exclude-from`, `--file`, `--recursive`, `-R`, `-d`, `-f`, `-r`
- `jq`: `--argfile`, `--from-file`, `--library-path`, `--rawfile`, `--slurpfile`, `-L`, `-f`
- `sort`: `--compress-program`, `--files0-from`, `--output`, `--random-source`, `--temporary-directory`, `-T`, `-o`
- `wc`: `--files0-from`
[//]: # "SAFE_BIN_DENIED_FLAGS:END"
[//]: # "SAFE_BIN_DENIED_FLAGS:END"
Safe bins also force argv tokens to be treated as **literal text** at
execution time (no globbing and no `$VARS` expansion) for stdin-only
segments, so patterns like `*` or `$HOME/...` cannot be used to smuggle
file reads.
Safe bins also force argv tokens to be treated as **literal text** at
execution time (no globbing and no `$VARS` expansion) for stdin-only
segments, so patterns like `*` or `$HOME/...` cannot be used to smuggle
file reads.
</Accordion>
</Accordion>
<Accordion title="Trusted binary directories">
Safe bins must resolve from trusted binary directories (system defaults
plus optional `tools.exec.safeBinTrustedDirs`). `PATH` entries are never
auto-trusted. Default trusted directories are intentionally minimal:
`/bin`, `/usr/bin`. If your safe-bin executable lives in
package-manager/user paths (for example `/opt/homebrew/bin`,
`/usr/local/bin`, `/opt/local/bin`, `/snap/bin`), add them explicitly to
`tools.exec.safeBinTrustedDirs`.
</Accordion>
<Accordion title="Trusted binary directories">
Safe bins must resolve from trusted binary directories (system defaults
plus optional `tools.exec.safeBinTrustedDirs`). `PATH` entries are never
auto-trusted. Default trusted directories are intentionally minimal:
`/bin`, `/usr/bin`. If your safe-bin executable lives in
package-manager/user paths (for example `/opt/homebrew/bin`,
`/usr/local/bin`, `/opt/local/bin`, `/snap/bin`), add them explicitly to
`tools.exec.safeBinTrustedDirs`.
</Accordion>
<Accordion title="Shell chaining, wrappers, and multiplexers">
Shell chaining (`&&`, `||`, `;`) is allowed when every top-level segment
satisfies the allowlist (including safe bins or skill auto-allow).
Redirections remain unsupported in allowlist mode. Command substitution
(`$()` / backticks) is rejected during allowlist parsing, including inside
double quotes; use single quotes if you need literal `$()` text.
<Accordion title="Shell chaining, wrappers, and multiplexers">
Shell chaining (`&&`, `||`, `;`) is allowed when every top-level segment
satisfies the allowlist (including safe bins or skill auto-allow).
Redirections remain unsupported in allowlist mode. Command substitution
(`$()` / backticks) is rejected during allowlist parsing, including inside
double quotes; use single quotes if you need literal `$()` text.
On macOS companion-app approvals, raw shell text containing shell control
or expansion syntax (`&&`, `||`, `;`, `|`, `` ` ``, `$`, `<`, `>`, `(`,
`)`) is treated as an allowlist miss unless the shell binary itself is
allowlisted.
On macOS companion-app approvals, raw shell text containing shell control
or expansion syntax (`&&`, `||`, `;`, `|`, `` ` ``, `$`, `<`, `>`, `(`,
`)`) is treated as an allowlist miss unless the shell binary itself is
allowlisted.
For shell wrappers (`bash|sh|zsh ... -c/-lc`), request-scoped env
overrides are reduced to a small explicit allowlist (`TERM`, `LANG`,
`LC_*`, `COLORTERM`, `NO_COLOR`, `FORCE_COLOR`).
For shell wrappers (`bash|sh|zsh ... -c/-lc`), request-scoped env
overrides are reduced to a small explicit allowlist (`TERM`, `LANG`,
`LC_*`, `COLORTERM`, `NO_COLOR`, `FORCE_COLOR`).
For `allow-always` decisions in allowlist mode, known dispatch wrappers
(`env`, `nice`, `nohup`, `stdbuf`, `timeout`) persist the inner executable
path instead of the wrapper path. Shell multiplexers (`busybox`, `toybox`)
are unwrapped for shell applets (`sh`, `ash`, etc.) the same way. If a
wrapper or multiplexer cannot be safely unwrapped, no allowlist entry is
persisted automatically.
For `allow-always` decisions in allowlist mode, known dispatch wrappers
(`env`, `nice`, `nohup`, `stdbuf`, `timeout`) persist the inner executable
path instead of the wrapper path. Shell multiplexers (`busybox`, `toybox`)
are unwrapped for shell applets (`sh`, `ash`, etc.) the same way. If a
wrapper or multiplexer cannot be safely unwrapped, no allowlist entry is
persisted automatically.
If you allowlist interpreters like `python3` or `node`, prefer
`tools.exec.strictInlineEval=true` so inline eval still requires an
explicit approval. In strict mode, `allow-always` can still persist benign
interpreter/script invocations, but inline-eval carriers are not persisted
automatically.
If you allowlist interpreters like `python3` or `node`, prefer
`tools.exec.strictInlineEval=true` so inline eval still requires an
explicit approval. In strict mode, `allow-always` can still persist benign
interpreter/script invocations, but inline-eval carriers are not persisted
automatically.
</Accordion>
</AccordionGroup>
</Accordion>
</AccordionGroup>
### Safe bins versus allowlist