Repository navigation
#635 [security][tools] Bash の cd・pushd の行き先が glob・brace のとき、作業ディレクトリを決められないとして検査する - #638
Merged
Kewton merged 2 commits intoOct 9, 2026
Conversation
A `cd`/`pushd` destination holding a glob or brace metacharacter
(`* ? [ ] { }`) added no working-directory candidate and no "cannot
determine" mark, so a following relative path was judged against the
workspace root alone and an outward symlink inside the destination let a
read or write escape (Issue #635, found reviewing #613).
The walk now flags such a destination `glob_destination` and, like the
existing CDPATH/loop/function cases, `undecidable`, so the write side
keeps its existing refusal. The second stage refuses the `/`-less
relative words under the new mark too; the mark is narrower than
`undecidable` and is set only for a glob/brace destination, so a command
with no `cd` (`env | grep CDPATH`, `echo $CDPATH`) keeps its handling.
A quoted or escaped bracket (`cd "s[2]"`) is flagged the same way, since
the lexical read cannot tell it apart from an executed one.
Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
Pin two behaviours that had no failing test (Issue #635 review, cargo mutants missed 3 / 1): - `Inspection::merge` must union the glob-destination mark: a unit test where only one carriage-return reading saw a glob or brace destination asserts the merged mark survives, so a `|=` read as `&=` fails. The integration shape `cd \rs2* && cat lf4` fixes R=1. - The candidate cap must count a growth that passes MAX_CANDIDATES without landing on it: forty repeated `cd sub` add one candidate each, then `cd r` doubles the set past the bound. A unit test asserts the walk is undecidable and an integration test asserts the relative write is refused, for the `cd` and `pushd` branch alike, so a `>` read as `==` fails. Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
Kewton
deleted the
feature/issue-635-security-tools-bash-cd-pushd-1-glob-613
branch
October 9, 2026 08:58
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.
概要
Bash の閉じ込めの検査で、
cd・pushdの行き先が glob・brace の文字(*・?・[・]・{・})を含むと、作業ディレクトリの候補にも「決められない」の印にもならず、その後の相対パスが検査されていませんでした。行き先のディレクトリの中の外向き symlink を通して、外を読み書きできました(例:cd s2* && cat lf4、cd s2* && echo x > lf4)。#613 の merge 前レビュー(H-10)で見つけた、#613 より前からある見逃しです。この PR は、Issue 本文の設計(案 1)どおり、glob・brace を含む行き先を「作業ディレクトリを決められない」とみなして検査します。
変更(対象 3 ファイル、+344/−8)
src/tools/bash_write_guard/working_directory.rs:Inspectionにglob_destinationの印を足す。cd・pushdの最初の位置引数(-P・-L・--の後も含む)が glob・brace の文字を含むと印を立て、undecidableにもする。CR の 2 つの読み方の和(merge)では OR。引用・エスケープした字どおりの括弧も同じ扱い(字句の読み方が区別しないため)。src/tools/bash.rs:/のない語と相対の候補を確かめる分岐の条件に|| glob_destinationを足しただけ。拒否は既存のpath_reference_rejection。tests/issue635_bash_glob_cd_destination.rs(新規):本文の表の全部の形(読み取り 24 形と root の絶対パスの glob、書き込み、保護ファイル)、CR の和、候補の上限、cd s2*単独、値が変わらない形(cd sub && …、cd src && ls *、cat s2*/x、env | grep CDPATH、echo $CDPATH)。[security][tools] Bash の 2 段目の path 検査が、$・glob・動的な値で静的な相対パスや展開先を確かめず、ワークスペース外を読める(#571 を統合) #582 の corpus の表と既存の試験のファイルは変えていない。検証
commandmate verifyの 15 ゲート:develop2a078debを取り込んだ HEAD で 15/15 pass(da7292b0、scope 3 本、違反 0)。TMPDIR=/tmp cargo test --test issue635_bash_glob_cd_destination --test issue568_bash_cwd_write_targets --test issue582_bash_read_candidates(CI と同じ条件を作るため):取り込んだ HEAD で exit 0、7 passed・0 failed、28 passed・0 failed、7 passed・0 failed(issue568・issue582・issue635 の順)。2a078debの src + この PR のテスト):新しい 4 本が FAIL(cd s2* && cat lf4、cd s2* && echo x > lf4、cd s2* && rm tests/spec.rs、cd s2*が拒否されない)。値が変わらないことを確かめる 1 本は develop でも pass。cargo mutants --jobs 1、--in-diff、--libと結合テスト 3 本、17 件):1 回目は missed 3。許可が増える向きの 2 件(mergeの|=→&=、候補の上限の>→==)はテストを足して直した。2 回目は caught 12・missed 1・unviable 4。残る 1 件は上限の>→>=(ちょうど 64 で上限の印が立つ、厳しくする向き)。builtin・command・env・\cdなど)、オプション、リダイレクト、複合コマンドの抜け道も拒否されることを確かめた。意図した誤拒否
cdの後のコマンドは、ワークスペースの中に留まる読み書きでも拒否される(cd s2* && ls、cd s2* && cargo test、cd s2*単独)。行き先を字どおりに書けば通る(cd s2 && …)。cd "src/app/[id]" && cat page)も拒否される。root からの相対パスで書けば通る(cat "src/app/[id]/page")。記録の 436 件では 0 件、参考の母集団(約 5.9 万件)では 3 件の形。字どおりの括弧を区別して候補に足すのは後続の候補。Refs #635
🤖 Generated with Claude Code