Skip to content

fix(claude): git許可の広範なワイルドカードとフックのfail-openを修正 - #76

Merged
tunepolo merged 2 commits into
mainfrom
fix/git-permission-sandbox-escape
Aug 9, 2026
Merged

fix(claude): git許可の広範なワイルドカードとフックのfail-openを修正#76
tunepolo merged 2 commits into
mainfrom
fix/git-permission-sandbox-escape

Conversation

@tunepolo

@tunepolo tunepolo commented Aug 8, 2026

Copy link
Copy Markdown
Owner

背景

#75 マージ後、バックグラウンドのセキュリティレビューから以下3つの重大度の高い指摘を受けた(レビューの完全な詳細は本セッションには配信されず要約のみだったため、指摘対象のファイルを自分で再点検して具体化した)。

修正内容

1. ALLOWLIST SEMANTIC ESCAPE / 任意コード実行

permissions.allowBash(git *) は、git -c core.pager=...git -c core.editor=...git config alias.x '!任意コマンド' のような gitのグローバルオプション経由の任意コマンド実行まで無確認で許可していた。
→ 安全なサブコマンド単位(git status, git log, git diff, git commit, git push(引数なし)等)の明示的な許可リストに置き換え、-c/-C が先頭に来るパターンは一切マッチしないようにした。

2. FAIL-OPEN STATE DRIFT(フックの検知漏れ・失敗時の素通り)

PreToolUse フックは dangerouslyDisableSandbox フラグのみを grep でチェックしており、(a) 上記1のgit経由の任意実行は検知対象外、(b) grepが何らかの理由で失敗すると無条件で exit 0(素通り)するfail-open設計だった。
jq でJSON構造から tool_input.command / dangerouslyDisableSandbox を明示的に抽出する方式に変更し、git -c/-C/--exec-path/--upload-pack/--receive-pack の使用も検知して承認を要求するようにした。

3. Bash経由の機密ファイル読み取り抜け(Readツール限定だったdenyの拡張)

permissions.denyRead(**/*.pem) 等はReadツールのみに効き、Bash(cat foo.pem) のような同等アクセスは sandbox.filesystem.denyRead の固定パス(~/.ssh/等)でしか防げていなかった。
sandbox.filesystem.denyRead**/.env, **/secrets/**, **/credentials, **/*.pem, **/*.key 等の汎用パターンを追加。

意図的に対応を見送った点(残課題)

sandbox.excludedCommands にある docker/gh/gcloud/aws/kubectl/terraform/chezmoi の広範なサンドボックス除外(前方一致のため複合コマンドでのチェイン回避リスクが残る)は、SSH経由のgit操作やDockerソケット、各クラウドCLIのプライベートエンドポイント等、サンドボックス化すると壊れる可能性のある実運用への影響を安全に検証できなかったため、本PRでは対象外とした。個別に動作確認しながら段階的に対応する別PRが必要。

テスト

  • jq . dot_claude/settings.json でJSON構文を検証
  • 新しいフックコマンドを dangerouslyDisableSandbox: true / git -c core.pager=evil log / git status(安全系) / ls -la(無関係) の4パターンでstdin経由で手動実行し、意図通りに ask / silent が分岐することを確認
  • chezmoi apply 後、実際の日常的なgit操作(status/log/diff/commit/push等)で不要な確認プロンプトが増えていないか確認

- permissions.allow の Bash(git *) を廃止し、安全なサブコマンド単位の許可に限定
  (git -c/-C 等のグローバルオプションによる任意コマンド実行を無確認で許可していたため)
- PreToolUse フックを dangerouslyDisableSandbox 検知のみから、
  git -c/-C/--exec-path 等の危険なグローバルオプション使用も検知するよう拡張
  (grep失敗時に無条件で素通りするfail-open設計だった点も、jqでの構造化抽出に変更して解消)
- sandbox.filesystem.denyRead に .env/secrets/credentials/*.pem/*.key 等の
  汎用パターンを追加し、Bash経由でも permissions.deny の Read(...) 相当の
  機密ファイル保護が効くようにした
--upload-pack/--receive-pack は git fetch/pull/push/clone のサブコマンドの
後に置かれるフラグであり、「gitの直後」しか見ていなかった前回の修正では
実際の攻撃パターン(例: git fetch origin --upload-pack=evil)を検知できて
いなかった。

- フックの正規表現を「gitの直後」限定から、--upload-pack/--receive-pack/
  --exec-path はコマンド文字列中のどこにあっても検知する方式に変更
- -c/-C は誤検知(tar -C, curl -c等)を避けるため、"git"という単語が
  コマンド中に存在する場合のみ検知する方式に変更
- GIT_SSH_COMMAND=/GIT_CONFIG_*= の環境変数プレフィックスも新たに検知
- permissions.deny にも Bash(git * --upload-pack*) 等を追加し、
  フックだけでなく許可ルール側でも git fetch */git pull * のワイルドカード
  経由の抜けを二重に塞いだ
@tunepolo
tunepolo merged commit dd7afbc into main Aug 9, 2026
5 checks passed
@tunepolo
tunepolo deleted the fix/git-permission-sandbox-escape branch August 9, 2026 08:39
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.

1 participant