Skip to content

[security][tools] Bash の作業ディレクトリを変えるオプションの検査が、長いオプションの省略形・短いオプションのまとまり・git の全体オプションの後の形で抜ける(#637 のレビューで発見) #645

Closed

Description

@Kewton

背景

#637 の merge 前レビュー(H-16、2026-10-09)で見つけた、Bash の閉じ込めの検査の既存の見逃しです。#637 の前の develop にもあり、#637 で緩んだものではありません(2026-10-10、利用者承認で起票)。着手前調査(H-17、2026-10-10)で、develop c98bdc7c の値を確かめ、設計を決めました。判定の関数を tempdir の fixture に対して呼び、結果を見ただけです。

問題

#637 で、オプションで作業ディレクトリを変える形を表にして検査するようになりました。ただし次の書き方の変種では、表のオプションを見つけられず、その後の相対パスが検査されません(R=0)。オプションの書き方を変えるだけで、ワークスペースの中の symlink を通して外のファイルを読めます。入力と値は「根拠」の表にあります。

  1. 長いオプションの省略形:GNU・bsdtar などは、長いオプションの一意な接頭辞を受け付けます(H-16 で、macOS の bsdtar 3.5.3 と GNU Make 3.81 で効くことを確かめた)。検査は名前を完全一致でだけ照合します。
  2. 短いオプションのまとまりで、値をとる別のオプションが C を値として食う形:検査はまとまりの C をオプションとみなし、次の語を値として読み飛ばすので、その後の本物のオプションを見ません。
  3. git の値をとる全体のオプションが先にある形:検査は、その値の語を subcommand とみなして走査を止めます。
  4. 表に無いプログラム:npm の短い名前 -C(--prefix と同じ)が表に無い。
  5. 空の値の理由の path:[tools] Bash で引用した字どおりの括弧のディレクトリへ cd する形(Next.js の [id])が誤って拒否される(#635 の意図した誤拒否、#637 から分離) #643 に移しました(同じ関数を [tools] Bash で引用した字どおりの括弧のディレクトリへ cd する形(Next.js の [id])が誤って拒否される(#635 の意図した誤拒否、#637 から分離) #643 が変えるため)。

設計(H-17 で決定)

  1. 表のプログラムの長いオプションは、表の長い名前の空でない接頭辞なら、その名前とみなします(--name=value と --name value の両方)。表のプログラムの未知の長いオプションを「決められない」にする案は、参考の記録の 9,198 件(15%)に印が立つため採りません。
  2. オプションの値として読んだ語が - で始まるとき(-- を除く)は、その語を値として記録したうえで、その語も続けて走査します。値を記録するので、- で始まる名前のディレクトリも今どおり候補になります。プログラムごとに値をとる短いオプションの表を持つ案は、表の保守が要り、漏れが穴になるため採りません。
  3. git の全体のオプションのうち、値を別の語にとるもの(-c・--git-dir・--work-tree・--namespace・--super-prefix・--config-env・--attr-source)は、値の語ごと読み飛ばして走査を続けます。= でつなぐ形と値をとらないオプションは、今のままです。未知の全体のオプションでは git 自体がエラーで止まるので、今どおり走査を止めます。
  4. 表の npm に短い名前 -C を足します。ほかのプログラムは足しません:tmux -c(後で動くコマンドの文字列の作業ディレクトリで、検査はその文字列の中を読まない)、docker -w(container の中の path)、unzip -d(展開先、つまり書き込み先の問題で、別の Issue にする)、meson -C・gradle -p(参考の記録に 0 件、後の語は target の名前)。find -execdir は範囲の外です。
  5. 表は作業ディレクトリのオプションの解析の中だけで変えます。候補を足す側の処理は変えません。

誤拒否の見積り

  • 記録(agent の Bash コマンド 436 件):H-17 の試作で値の変化は 0 件。
  • 参考(このリポジトリで動いた Claude Code の Bash コマンド 59,358 件):値の変化は 0 件。表の名前の接頭辞の形は 0 件、値をとる全体のオプションで始まる git は 151 件、npm -C は 0 件。
  • 候補を足すだけなので、新しく拒否になるのは、足した先に外向き symlink があるか、値が決められない(glob・$・.. など)ときだけです。

受け入れ条件

対象ファイル

  • src/tools/bash_write_guard/option_directory.rs
  • tests/issue645_bash_option_directory_variants.rs

参照

根拠

fixture:ワークスペースの中の sub の中の lf2 は、外のファイルを指す symlink。sub/f と f は普通のファイル。R:2 段目の閉じ込めの判定。値は develop c98bdc7c と H-17 の試作。

表 1(R=0 → R=1 にする)

項目 入力(例) develop 試作
1 tar --dir=sub -cf - lf2、tar --direc sub -cf - lf2、tar --dir sub -cf - lf2、make --dir=sub lf2、env --ch=sub cat lf2、env --chd sub cat lf2、sudo --chd=sub cat lf2、patch --dir=sub -i lf2、just --working-dir sub cat lf2、pnpm --di sub cat lf2、npm --pref sub x lf2 R=0 R=1
2 tar -cfC -C sub lf2、tar -cfC --directory=sub lf2、tar -cfC -Csub lf2、tar -fC -Csub lf2、make -fC -C sub lf2、sudo -uD -D sub cat lf2 R=0 R=1
3 git -c k=v -C sub log lf2、git --git-dir x -C sub log lf2、git --work-tree sub -C sub log lf2、git --namespace n -C sub log lf2 R=0 R=1
4 npm -C sub run x lf2、npm -C sub exec cat lf2 R=0 R=1

表 2(許可のまま)
git -C sub status、make -C sub、tar -C sub -cf - f、grep -C 3 x f、git log -C sub、git -c color.ui=never status、git -c k=v -C sub status、git --no-pager log -C、git commit -C HEAD、tar --exclude=x -cf - f、make --no-print-directory -C sub、make -f Makefile test、cargo test --no-fail-fast、cargo --manifest-path x/Cargo.toml test、npm --prefix sub run build、sudo -u root -D sub cat f、env --ignore-environment cat f、tar -xzf a.tar -C sub

表 3(今の値のまま)

入力(例) 値 理由
git -c core.pager=cat -C sub show HEAD:lf2 R=0 HEAD:lf2 は git の中の object の名前で、ファイルの path ではない(元の本文の表から外した)
meson -C sub lf2、gradle -p sub lf2、tmux -c sub cat lf2、docker -w sub cat lf2、unzip -d sub a.zip lf2 R=0 設計 4 で表に足さない
git --no-pager -C sub log lf2、git -P -C sub log lf2、git --git-dir=x -C sub log lf2 R=1 今も検査される

コード(develop c98bdc7c)

  • 長いオプションの完全一致の照合:src/tools/bash_write_guard/option_directory.rs:128-147
  • まとまりの解析と値の読み飛ばし:同じファイルの :149-164
  • git の全体のオプションで走査を止める:同じファイルの :169-173
  • 表:同じファイルの :81-101

関連(参考)

Activity

  1. added a commit that references this issue on Oct 10, 2026
  2. Kewton commented on Oct 11, 2026

    @Kewton
    OwnerAuthor

    develop に merge 済み(PR #654、merge 後の develop 9047eb3 で CI・acceptance success)。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions