#566 [security][tools] Bash の書き込み検査が env・sudo・timeout などの前置きや { … } の中の書き込みを認識せず、ワークスペース外へ書き込める(#509 の調査で発見) - #574
Merged
Kewton merged 6 commits intoOct 2, 2026
Conversation
Bash の書き込み検査が segment の先頭語だけで program を決めていたため、 env・sudo・timeout・nice・予約語などの前置きの後ろの書き込みを ワークスペース外と判定できなかった(#566)。新しい葉 module `bash_write_guard/command_prefix.rs` に前置きの表と剥がし方を置き、 不動点まで剥がしてから program を決めるようにした。剥がし方が決まらない形は 残りの語を走査し、書き込み program か別の前置きがあれば拒否に倒す。 判断: `sudoedit` の operand を書き込み先として扱う(Issue 設計の「sudoedit は operand が書き込み先」に対応) 判断: `env -S` の operand は語を空白で分割してから走査する(引用された `tee /tmp/f` を検出するため) 読み替え: 「残りの語の basename を走査」は、決められなくなった前置きの直後以降の語を対象とした 本文に無い指摘: cargo mutants を --jobs 3 で回すと共有 target dir の競合で偽の生存変異が出る(記録した missed の `index - 1` / `offset - 1` は直接再適用すると overflow panic で kill される);report に記録 Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
レビューで見つかった前置きの表の抜け 4 件をふさぐ。 - env -S / --split-string / -iS の文字列 operand を取り出して空白で分け、書き込み program か前置きがあれば拒否する - nohup・builtin は直後の -- を飛ばしてから program を決める - sudo の -k / --reset-timestamp を「実行しない」の表から flag の表へ移す - 走査の書き込み program の一覧に sudoedit を足す テストの不足(env -C / --chdir / sudo -D / env -i -- / exec -- / exec -X、env -S の各形、深さの境目 16/17、command -)も追加。 判断: 設計 5(exec の前置きと shell の前置きの区別)は使う側がないため今回は実装しない(#568 で入れる) 判断: env -S の値は空白分割した各語の basename が書き込み program か前置きのとき拒否に倒す 本文に無い指摘: リーダーが cargo mutants を回すため、ワーカー側では実行していない Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
cargo mutants の生存 34 件のうち、offset・cursor のずれが観測できる形を足す。 値を取る option の後ろに workspace 内の書き込み program を置き、閉じ込め許可・ has_recognized_mutation true・保護 path 検出が path を返す の 3 点を固定する。 unknown option と bare `-` の境目、short_cluster_split_string の境目も直接固定。 本文に無い指摘: `env -Sx tee out.txt` と `env -iS x tee out.txt` は -S の値に書き込みが無いのに拒否される。short_cluster 経路が -S の値を使い切らず continue しないためで、fail-closed の安全側だが設計の「誤拒否を絞る」より厳しい。製品は凍結のため未修正、報告のみ 判断: 352:48・469:13・470:13・529:36・563:32・600:32 は等価変異(到達しない len==1、fall-through も同じ Undecidable、args.get(offset) が常に Some)と判断しテストで殺さない 判断: 312:45・315:25 は指示どおり等価として扱い無視する Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
…able operands R1: 決められない形の走査(unresolvable → contains_write_or_prefix)でも env の -S の値を 取り出す。attached(-Stee)・flag をまとめた -iuX -S…・--split-string=…・-S +次の語の すべてを対象にし、走査が tee・cp などを見落とさないようにする。 R2: -S の値に " ' \ $ のいずれかが含まれていたら、確かめられない書式として拒否する (安全側)。含まれなければ今と同じく空白で分けて走査する。 結合テストに R1 拒否 5 行・R2 拒否 7 行・許可 2 行を追加。直す前(eddc6620 相当)では `env -S'"tee" /tmp/f'` と `env -uX -S'tee /tmp/f'` がいずれも拒否されず失敗し、直した後で 通ることを実測した(二点測定)。 判断: R2 の「確かめられない」判定は " ' \ $ の 4 文字を含む場合とする(指示どおり) 本文に無い指摘: 先に報告した `env -Sx tee out.txt` / `env -iS x tee out.txt` の誤拒否は今回の R1/R2 では変わらない(step_env の short_cluster 経路が値を使い切らず continue しないため)。拒否側で安全 Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
… scan
unresolvable_scan_rejects の 2 生存(734:32 の ||→&&、735:50 の index + 1→index * 1)を
殺す行を足す。決められない前置きの後ろで -S / --split-string が独立した語になり、その次の語が
R2 の対象("・'・\・$ を含む)で write の語を含まない形を拒否の表に追加した。次の語を通常の語と
して走査しても tee 等が見つからないため、次語の取り出し経路だけが拒否に到達する。
拒否: X=tee env --unknown -S '${X} /tmp/f' / X=tee env --unknown --split-string '${X} /tmp/f' /
env -C sub -S '${X} /tmp/f' / env --unknown -S 'a\_b'
許可: env --unknown -S(-S が最後の語で値なし)
Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
env -S の綴りを 1 つずつ塞ぐ方針をやめ、値を問わず一律に拒否する。H-04 で E1〜E3 の
blocker が出たため。
- step_env: env_requests_split_string で、-S を含む短い option のまとまり(-S・-iS・-vS・
-0S・-iuXS…)と --split-string の接頭辞(--s…--split-string、= の有無を問わず)を値を見ずに
Step::Reject にする。値をとる option(-u・-C・-P)が先頭なら残りはその値として扱い対象外
(-uSOMETHING・-u NAME・-u S)。
- 走査(unresolvable_scan_rejects)は値の取り出しをやめ、語ごとの一律判定と
contains_write_or_prefix だけにする(env -uX --unknown -S… でも拒否)。
- 新 Resolution::UnverifiableSplitString を追加し、理由を「env -S / --split-string」として
拒否する(Undecidable とは別扱い)。
- 消した関数: env_split_string_unsafe、short_cluster_split_string。Step::Reject は該当の
option 語を持ち、bash_write_guard の write_targets/confinement_rejection に配線した。
変えた期待の行:
- 結合 許可→拒否へ移動: env -S'cargo test' / env -S / env --split-string / env --unknown -S /
env -S x tee out.txt / env --split-string x tee out.txt / env --split-string=x tee out.txt。
結合 拒否に追加: env -iS '"tee" /tmp/f' / env -vS 'tee\_/tmp/f' / env -0S '${X} /tmp/f' /
env -S'-Stee /tmp/f' / env -S'--split-string=tee /tmp/f' / env --split='tee /tmp/f' /
env --s='tee /tmp/f' / env --split-str='cp a.txt /tmp/f' / env -iuXS 'x' /
env -uX --unknown -S 'cargo test' / sudo env -S'x y' / timeout 5 env -S'x y'。
結合 許可に追加: env -i PATH=/usr/bin cargo test / env -u HOME cargo test /
env -uSOMETHING cargo test / env -u S cargo test。
- 単体 resolution_table: env -Scargo test・env -S・env --split-string を no_execution から
UnverifiableSplitString へ、-S を含む他の行も同じく更新。command_prefix_marks_unresolvable_chains
の env -S 行も UnverifiableSplitString へ。
- 単体 short_cluster_split_string_table を env_requests_split_string_table に置換。
- bash_write_guard の write_targets table の env -S 行を
("-S", UNVERIFIABLE_SPLIT_STRING_OPERATION) へ。
Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
7 tasks
Kewton
deleted the
feature/issue-566-security-tools-bash-env-sudo-timeout-509
branch
October 2, 2026 15:35
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
src/tools/bash_write_guard/command_prefix.rs(new): peels command prefixes before choosing the program whose write targets are checked.env,command,builtin,exec,nohup,sudo/doas/sudoedit,timeout/gtimeout,nice,ionice,stdbuf,timeand/usr/bin/time,setsid,caffeinate,arch.!,{/}, the reserved words, andfunction NAME.env -C,--chdir,sudo -s/-i/-D/-R)env -S/--split-stringis rejected in every spelling:S(-S,-iS,-vS…)--split-string(--s…--split-string)sudo -e/sudoeditoperands and/usr/bin/time -o FILE.src/tools/bash_write_guard.rs: wires the resolved program intowrite_targets,confinement_rejection(new rejection reasons), and the shared extraction.has_recognized_mutationandprotected_path_mutationuse that extraction.tests/issue566_bash_command_prefix_write_targets.rs(new): integration tests throughpath_confinement_rejection.Verification
dbc19a3f(commandmate verify --task).command_prefix.rs, measured with--jobs 1re-runs:Undecidable/NoExecutionresult through a later branch.env -Sspellings.issue567_bash_glob_write_targets,issue428_bash_path_tokens,bash_workspace_confinement.Notes
env tee out.txtandtimeout 5 tee out.txtnow count as writes, sobash:verifyno longer auto-allows them.timeout 600 cargo test,env RUST_LOG=debug cargo test,nice cargo build,npm test, …env -S'cargo test'and other uses ofenv -Ssudo -Safter an unresolvable optionSis really a value (env -iuS …)xargs,find -exec,sh -c,eval,su -c,watch,script -c([security][tools] Bash の字句検査では、プログラム経由の間接書き込みや検証コマンドの副作用を閉じ込められない #502)chrt,taskset,unshare,busybox)$'…'in the lexer (pre-existing, tracked separately)cdis recorded after either kind, which is the strict side.>|と数字でない>&を redirect として読まず、ワークスペース外へ書き込める(#509 の調査で発見) #565, [security][tools] Bash の書き込み先の glob・brace を展開前の文字列で判定するため、中の symlink を通ってワークスペース外へ書き込める(#509 の調査で発見) #567, [security][tools] Bash の書き込み検査が同じコマンドの cd・pushd の後の cwd を追わず、symlink を通ってワークスペース外へ書き込める(#509 の調査で発見) #568, [security][tools] Bash の 2 段目の読み取りの判定が、引用符のない glob・動的な値・glob を含む絶対パスで抜け、ワークスペース外を読める(#567 の調査で発見) #571, [security][tools] Bash の字句検査では、プログラム経由の間接書き込みや検証コマンドの副作用を閉じ込められない #502.Developed with the CommandMate parallel-dev harness (PM: Claude Code, leader: Claude_Dev, workers: Command Code).
🤖 Generated with Claude Code