bypassPermissionsにしても許可を求められる——Claude Code 2.1.259のcd複合コマンド誤検知を追った

bypassPermissionsにしても許可を求められる——Claude Code 2.1.259のcd複合コマンド誤検知を追った

Claude Code 2.1.259以降、Read()拒否ルールを設定しているとbypassPermissions/Auto Modeでも「cd DIR && grep」のような複合コマンドで許可プロンプトが出る不具合が起きている。Windows・macOS・Linux横断の複数報告とGitHub Issueの実測データ、現時点の回避策を整理した。

エンジニアのゆとです。

bypassPermissionsにしてるのに、cdを含むコマンドだけ急に確認を求められるようになった——という報告が、2026年9月2日のv2.1.259アップデート直後から立て続けに来ている。原因は.envや秘密鍵を守るためのRead()拒否ルールで、真面目に設定していた人ほど踏みやすいという、なかなか皮肉な不具合だ。

まず結論——現時点で未修正、影響はこの3条件が揃ったとき

対象は以下の組み合わせ。

  • Claude Codeバージョン: 2.1.257〜2.1.259(記事執筆時点の最新)
  • 設定: settings.json(ユーザー or プロジェクト)にRead()の拒否ルールを1つ以上設定している(Read(**/.env)やRead(**/*.pem)など、多くの人が秘密情報保護のために入れているやつだ)
  • 実行モード: autoまたはbypassPermissions

この3つが揃うと、cd <ディレクトリ> && grep ...のような「cdしてから相対パスで何かを読む」複合コマンドで、autoはもちろんbypassPermissionsですら許可プロンプトが出る。GitHub Issueでは#91650を軸に、Windows・macOS・Linuxそれぞれで独立した再現報告が上がっており、少なくとも4件が同一パターンで合流している。記事執筆時点(Issue報告から1日程度)でAnthropic側からの公式な反応や修正版はまだ出ていない。

Claude Codeで確認なしに実行されていた5つの穴、v2.1.214で修正
Claude Codeで確認なしに実行されていた5つの穴、v2.1.214で修正Claude Code v2.1.214で、dir/**の過剰マッチ・PowerShell 5.1・zshの変数添字・help/manの危険オプション・1万文字超コマンドという5つの権限チェック回避が修正された。それぞれの仕組みと実害範囲、バージョン確認とアップデートの手順までエンジニア視点で解説する。読む →

自分は7月に「確認なしに実行されていた5つの穴が塞がれた」という記事を書いた。今回はその真逆——穴を塞ぐための修正が、塞ぐべきでないところまで塞いでしまっている。

何が起きているか

一番シンプルな再現例はこれだ。cdの行き先が誰の目にも明らかな絶対パスのリテラルなのに、後続の相対パス読み取りが「解決不能」と判定されてプロンプトが出る。

cd D:/dev/myrepo && grep -rn pattern sub/dir/ | head -2
→ grep on 'sub/dir/' after a cd would search a directory that
  cannot be determined here, and a Read() deny rule is configured

報告されている再現パターンを見ていくと、共通点が見えてくる。

  • cdの後に;区切りでコマンドが続くケース(cd DIR; cmd)は、cdが絶対パスであっても十中八九プロンプトが出る
  • &&だけの単純なチェーン(cd DIR && grep ...)は基本的に許可されるが、その後にさらに;や別の&&が続くと途端に「解決不能」判定に切り替わる
  • サブエージェント(general-purposeなど)が実行したBashコマンドの確認プロンプトは、親セッション側に「◯◯エージェントからの確認」という形で出てくる。並列でサブエージェントを何本も走らせていると、ファイルを読むたびにこの確認が積み上がる
  • macOS・Linuxでの再現も複数報告されており、Windows Git Bash固有の問題ではない

コメント欄では「bypassPermissionsが実質意味をなさず、完全自律的な作業が不可能になった」という声や、「セキュリティを強化する側と自動化したい側、どちらを優先するかの設計がそもそも破綻している」という指摘も出ている。

なぜ起きるのか——2.1.259の意図とのズレ

これは偶然のバグではなく、直前の意図的な修正が引き金になっている。2.1.259のリリースノートにはこうある。

Fixed Bash Read() deny rules not covering files given as option values (--ignore-revs-file=.env, -f.env, @file), git diff/git grep file operands, or cd DIR && cat FILE compounds; grep -r/cp -r over a directory holding a denied file now asks

つまり2.1.259は「cd DIR && cat FILEのような複合コマンドでRead()拒否ルールが素通りしていた抜け道」を意図的に塞ぎに来ている。この修正自体は正しい。以前はcd .env-secrets && cat configのような形にすれば拒否ルールをすり抜けられていたわけで、それが直ったのはセキュリティ的に前進だ。

問題はその実装の「解決不能」判定が過剰反応している点にある。Issue報告者の実測によれば、cdのオペランドが変数展開もグロブも含まない完全なリテラル文字列であっても、コマンドの後半に;や複数の&&が挟まると解決を放棄してとりあえずプロンプトを出す、という挙動になっているようだ。本来「解決できるが未実装」なだけのケースまで「解決不能につき要確認」に倒しているせいで、安全なはずのbypassPermissionsでも人間の判断待ちが発生してしまう。

公式ドキュメントのPermission modesには「拒否ルールはbypassPermissionsを含むすべてのモードでブロックする」と明記されている。つまり今回の挙動は仕様通りではあるのだけれど、bypassPermissionsを選んだ人が期待しているのは「拒否ルールに一致しない限り黙って進む」ことであって、「拒否ルールに一致するかもしれないから毎回聞く」ことではない。この温度差が、今回の不満の核心だと思う。

別物なので注意——「50サブコマンド上限」の脆弱性とは違う話

このタイミングでもう一つ、Read()拒否ルール関連の話題が海外セキュリティブログで出回っている。50個を超えるサブコマンドを含む複合コマンドでは、権限チェックの解析が上限に達して拒否ルールがまるごとスキップされ、プロンプトインジェクション経由の悪意あるコマンドが素通りしうる、という脆弱性報告だ。

方向性が正反対なので、混同しないよう整理しておく。

50サブコマンド上限の脆弱性今回のcd複合コマンド誤検知
何が起きるか拒否ルールが効かず素通りする拒否ルールと無関係な安全な操作までブロック(要確認)
リスクの向きセキュリティが弱くなる方向利便性が落ちる方向(安全側に倒れすぎ)
対象コマンド50個超のサブコマンドを含む長大な複合コマンドcdを含む短い複合コマンド全般

一方は「守れているはずのものが守れていない」、もう一方は「守らなくていいものまで止められる」。どちらもRead()拒否ルールがらみだけれど、実害の種類が真逆なので、自分の環境がどちらに該当するかは切り分けて考えたほうがいい。

今すぐの回避策——どれもトレードオフ付き

修正版が出るまでの間、現実的な選択肢は3つある。どれも一長一短で、「これさえやれば万事解決」というものはない。

1. 複合コマンドの書き方を変える

cd DIR && cmd1; cmd2のような;区切りをやめて、絶対パスを直接コマンドに渡す形にする。

# プロンプトが出やすい書き方
cd /path/to/repo && grep -rn pattern sub/dir/ | head -2; echo done

# 出にくい書き方(cdを使わず絶対パスで完結させる)
grep -rn pattern /path/to/repo/sub/dir/ | head -2

CLAUDE.mdに「Bashコマンドでcdを使うときは単独の&&チェーンで完結させ、;区切りや複数の&&は避ける」と一文入れておくだけでも、Claude側の生成コマンドの傾向はある程度変わる。ただしこれは対症療法で、Claudeがどう複合コマンドを組み立てるかを完全にはコントロールできない。

2. 該当のRead()拒否ルールを一時的に外す

一番手っ取り早いが、一番おすすめしない。.envや秘密鍵を守るために設定したルールを外せば当然プロンプトも消えるが、それは2.1.259が塞いだはずの抜け道を自分から開け直すことになる。作業内容的に秘密ファイルに一切触れない確信があるプロジェクトでの一時運用ならまだしも、常用は本末転倒だ。

Claude Codeのパーミッションプロンプトを設計する——allowlistとsettings.jsonで確認頻度を最適化する
Claude Codeのパーミッションプロンプトを設計する——allowlistとsettings.jsonで確認頻度を最適化するClaude Codeのパーミッションプロンプトが頻繁に出て作業が止まる問題を解決する。settings.jsonのallowlist設定、プロジェクト別権限とグローバル権限の使い分け、危険コマンドは残しつつ安全なコマンドを通す設計パターンを実装例付きで解説。読む →

3. 2.1.258以前にピン留めする

Issue報告者自身が「これを理由にチームを2.1.258に固定することを検討している」と書いている通り、選択肢としては現実的だ。ただし2.1.258は今回塞がれた抜け道(cd DIR && cat FILEでの拒否ルールすり抜け)がそのまま残っているバージョンでもある。プロンプトの煩わしさを取るか、拒否ルールの網羅性を取るかの二択で、後者を諦めることになる。

バージョン固定の具体的な手順は以前まとめた。

Claude Codeを前のバージョンに戻す方法——ダウングレードと`claude install`、二度と壊れないためのバージョン固定
Claude Codeを前のバージョンに戻す方法——ダウングレードと`claude install`、二度と壊れないためのバージョン固定Claude Codeがアップデート後に不安定になったときの戻し方を解説。claude installコマンドでの特定バージョンへの切り替え、npm/Homebrew別の手順、autoUpdatesChannelとminimumVersionでの固定、ダウングレードすべきか迷ったときの判断基準までまとめた。読む →

自分の運用ではどうするか

正直、まだ結論を出しかねている。自分のCLAUDE.md運用は「読む系はほぼ全部許可、書く系は都度確認」という設計にしていて、Read()拒否ルールも.env系だけは常に入れている。今回のバグは自分の環境(2.1.223、まだ2.1.257台に上がっていない)ではまだ再現していないので、実際にどれくらいの頻度でプロンプトが出るのかは自分の手元では確認できていない。Issue報告を読む限りサブエージェントを並列で走らせる運用ほど影響が大きそうなので、次にアップデートするときは複合コマンドを含むタスクで一度様子見してから本番運用に戻すつもりだ。

Claude Code Auto Mode 完全攻略 2026——2段階分類器の仕組み・カスタマイズ設定・安全な使い方
Claude Code Auto Mode 完全攻略 2026——2段階分類器の仕組み・カスタマイズ設定・安全な使い方Claude Code Auto ModeはShift+Tabで起動する自律承認モード。2段階分類器の仕組み(17%見落とし率含む)、--dangerously-skip-permissionsとの違い、カスタマイズJSON設定、Enterprise封鎖設計まで網羅。読む →

まとめ

Claude Code 2.1.257〜2.1.259で、Read()拒否ルールを設定している環境ではautoモードだけでなくbypassPermissionsでも、cdを含む複合コマンドが「解決不能」と誤判定されて許可プロンプトが出る不具合が起きている。原因は2.1.259で意図的に塞いだ別の抜け道(cd DIR && cat FILEでの拒否ルールすり抜け)の実装が、解決可能なケースまで一律プロンプト側に倒してしまっていることにある。記事執筆時点で公式の修正は出ていないので、複合コマンドの書き方を見直すか、拒否ルールの範囲を一時的に絞るか、バージョンを固定するかの中から、自分のプロジェクトのリスク許容度に合わせて選ぶことになる。

Anthropic側の対応が入り次第、この記事も更新する。

← 記事一覧に戻る