とことんDevOps | 日本仮想化技術のDevOps技術情報メディア

DevOpsに関連する技術情報を幅広く提供していきます。

日本仮想化技術がお届けする「とことんDevOps」では、DevOpsに関する技術情報や、日々のDevOps業務の中での検証結果、TipsなどDevOpsのお役立ち情報をお届けします。
主なテーマ: DevOps、CI/CD、コンテナ開発、IaCなど
読者登録と各種SNSのフォローもよろしくお願いいたします。

AIにrm -rfされないようにするために〜Claude Code編〜

本日は小ネタです。

日々のタスクや色々な調査にClaude DesktopやClaude Codeを活用しているのですが、どのAIを使ったとしても故意ではない「ファイルやディレクトリーをAIに勝手に消されて事故」みたいなことは起きてしまいがちなんですよね。 SNSとかで見ていると、頻繁に観測されたり、ITニュースとかで取り上げられるよくあるネタだと思います。

それに対する対策を調べてみると、一長一短あるようです。

Claude Codeの設定で回避してみる

例えばClaude Codeなら、設定例は次のドキュメントに載っています。permissionsで色々拒否するルールを書いていけば良いようです。

code.claude.com

例えば次のように記述すると、rmコマンドを拒否できます。 これが一番安全と言えばそうですが、rm -rf /とかrm -rf ~/のような問題のあるコマンドだけでなく、rm file.txtのような処理も全て拒否します。

{
  "permissions": {
    "deny": [
      "Bash(rm:*)"
    ]
  }
}

じゃあ、こう書いたらどうでしょう? 一見、rm -rf /とかrm -rf ~/が拒否されて良さそうですが、Claudeに聞いてみると 「"Bash(rm -rf:*)"はrm -rfで始まるコマンドをブロックしますが、オプションの順序や位置が変わると回避される可能性があります(例: rm -r -fやrm file -rfなど)。また、シェル演算子を使った回避(例: true && rm -rf /)や変数を使った回避(例: CMD=rm && $CMD -rf /)もありえる」とのこと。確かにそれはダメそうですね。

{
  "permissions": {
    "deny": [
      "Bash(rm -rf:*)"
    ]
  }
}

結論

最終的にはプロジェクトディレクトリーにCLAUDE.mdを書いて、次のような指示を記述するのが一番良いのかなと。

# セキュリティルール

## 危険なコマンドの制限

- `rm -rf /`、`rm -rf ~`、`rm -rf *` などの危険なrmコマンドは絶対に実行しないでください
- rmコマンドでは再帰的削除(`-r`オプション)は絶対に使わないでください
- ファイルを削除する前に、必ず削除対象を確認してください
- 許可されるrmパターン:特定のファイル名を指定した削除のみ(例:`rm file.txt`)

もしくは最初の例のように、rmコマンドは拒否してしまうのが適切そうです...と書いて終わりにしようと思ったのですが、危険なコマンドはrmコマンドだけではないのに今更気がつきました。

回避する方法として教えてもらったのは、「ちゃんとダメなコマンドを全部書いていく方法」と「サンドボックスを利用する方法」でした。

まず「ちゃんとダメなコマンドを全部書いていく方法」ですが、例えば... ただ、これだけで良いのかは今のところわかっていません。

{
  "permissions": {
    "deny": [
      "Bash(rm:*)",
      "Bash(unlink:*)",
      "Bash(find*-delete:*)",
      "Bash(mv*dev/null:*)",
      "Read(./.env)",
      "Read(./secrets/**)"
    ]
  }
}

「サンドボックスを強制する方法」は例えば

{
  "sandbox": {
    "enabled": true
  }
}

のような感じです。 サンドボックス化についての詳細は、ドキュメントにまとめられています。

code.claude.com

さらにClaudeに聞いたら、「あなたはDocker, Node.js, Python, GitHub.comをよくお使いですから、例えば次のような設定を書き加えると良いかもしれません」といったことを教えてくれました。これで問題があればまた教えてくださいだそうです。とりあえずの着地点はここら辺でしょうか。

最近Podmanも使っているので、それも書き加えてこんな感じにしています。

{
  "sandbox": {
    "enabled": true,
    "filesystem": {
      "allowedWritePaths": [],
      "deniedPaths": []
    },
    "network": {
      "allowedDomains": [
        "github.com",
        "npmjs.org",
        "pypi.org"
      ]
    },
    "excludedCommands": [
      "docker",
      "podman"
    ]
  }
}

とはいえ、一般的にはCLAUDE.mdにルールを書く方法が最も良さそうですね。