Skip to content

Bash拒否ルールがcdを含むパイプコマンドでプロンプトにダウングレードされていた問題の修正

原文(日本語に翻訳)

cd と他のセグメントが混在するパイプコマンドで、Bash(...) 拒否ルールがプロンプトにダウングレードされていた問題を修正しました。

原文(英語)

Fixed Bash(...) deny rules being downgraded to a prompt for piped commands that mix cd with other segments

概要

Claude Codeの権限設定では特定のコマンドを明示的に拒否するdenyルールを設定できます。このバグでは、cdコマンドと他のコマンドが組み合わされたパイプコマンド(例:cd /some/dir && dangerous_command)の場合、設定された拒否ルールが機能せず、拒否ではなく権限プロンプトに降格(ダウングレード)されてしまっていました。本来は「拒否」(実行不可)とすべきコマンドが「確認」(ユーザーの承認で実行可能)として扱われる問題でした。v2.1.98で修正され、cdを含む複合コマンドでも拒否ルールが正しく機能するようになりました。

基本的な使い方

修正前の動作(問題のある挙動)

json
// .claude/settings.json
{
  "permissions": {
    "deny": [
      "Bash(rm -rf *)",
      "Bash(format *)"
    ]
  }
}
bash
# 修正前の動作

# 単独のコマンド → 正しく拒否される
rm -rf /important/dir          # → 拒否(正常)

# cd と組み合わせたコマンド → 拒否ルールが適用されずプロンプト表示
cd /tmp && rm -rf /important/dir  # → 権限プロンプト(本来は拒否されるべき)
cd /dir; rm -rf .                 # → 権限プロンプト(本来は拒否されるべき)

修正後の動作(v2.1.98以降)

bash
# 修正後:cd を含む複合コマンドでも拒否ルールが正しく適用される

# 単独のコマンド → 拒否
rm -rf /important/dir          # → 拒否 ✓

# cd と組み合わせたコマンド → 拒否ルールが正しく適用
cd /tmp && rm -rf /important/dir  # → 拒否 ✓
cd /dir; rm -rf .                 # → 拒否 ✓

実践例

シナリオ1:危険なコマンドの完全な拒否(修正後)

cdを使ってディレクトリを移動してから危険なコマンドを実行するパターンが、拒否ルールで正しくブロックされます。

json
{
  "permissions": {
    "deny": [
      "Bash(rm -rf *)",
      "Bash(dd if=*)",
      "Bash(mkfs *)",
      "Bash(chmod 777 *)"
    ]
  }
}
bash
# 修正後:以下のすべてのパターンが拒否される
rm -rf /var/log/*                          # → 拒否 ✓
cd /var/log && rm -rf *                    # → 拒否 ✓
cd /var/log; rm -rf access.log             # → 拒否 ✓
cd /var && cd log && rm -rf .              # → 拒否 ✓

シナリオ2:特定ディレクトリでの操作制限(修正後)

特定ディレクトリへのcdを起点とした危険な操作をブロックします。

json
{
  "permissions": {
    "deny": [
      "Bash(* /etc/*)",
      "Bash(* /usr/bin/*)",
      "Bash(* /boot/*)"
    ]
  }
}
bash
# 修正後:システムディレクトリへのcdを含む操作も拒否される
cd /etc && cat shadow                      # → 拒否 ✓
cd /usr/bin; chmod +x malicious            # → 拒否 ✓

シナリオ3:ビジネスルールの強制(修正後)

組織のルールに基づいて特定のコマンドシーケンスを拒否する設定。

json
{
  "permissions": {
    "deny": [
      "Bash(git push --force *)",
      "Bash(git push -f *)",
      "Bash(kubectl delete *)"
    ]
  }
}
bash
# 修正後:cd を使ったパターンでも拒否ルールが機能する
cd /project && git push --force origin main  # → 拒否 ✓
cd /k8s-configs && kubectl delete pod --all  # → 拒否 ✓

シナリオ4:拒否ルールとプロンプトルールの違い(修正後の整理)

拒否(deny)ルールの動作(修正後):
- マッチするコマンドは問答無用で実行拒否
- ユーザーが承認しても実行できない
- cd を含む複合コマンドでも正しく機能する(修正済み)

プロンプト(ask)ルールの動作:
- マッチするコマンドはユーザーへの確認を求める
- ユーザーが承認すれば実行される

自動許可(allow)ルールの動作:
- マッチするコマンドは確認なしに自動実行される

優先順位: deny > ask > allow

注意点

  • この修正により、設定した拒否ルールがcdを含む複合コマンドに対しても確実に機能するようになりました。
  • 拒否ルールは最強の権限制限です。一度設定すると、ユーザーがそのコマンドを承認することができないため、設定には注意が必要です。
  • cdは通常「安全なコマンド」として扱われますが、cdの後に続く危険なコマンドに対する拒否ルールは正しく適用されます。
  • この修正前に「拒否されるはずのコマンドがプロンプトとして表示された」ことがある場合は、v2.1.98にアップデートすることで意図通りの動作になります。

関連情報