powered by TechFeed
表示モード
Deep Dive

Claude Codeの「今後は確認しない」承認が、2,539件のクレデンシャルをGitHubに漏洩させる — 正規フローだけで成立する落とし穴

11月7日、Guru Baranが「Claude Code's "Yes, and Don't Ask Again" Option Can Leak Passwords and API Keys to GitHub」と題した記事を公開した。Claude Codeの日常的な承認操作が、データベースパスワードや本番APIキーをGitHubに公開状態で残す——調査で確認されたのは104,185件のファイル中に散らばる2,539件のクレデンシャルだ。悪用や不正アクセスを必要とせず、正規の承認フローだけで発生する点が従来の脆弱性と根本的に異なる。

11月7日、Guru Baranが「Claude Code's "Yes, and Don't Ask Again" Option Can Leak Passwords and API Keys to GitHub」と題した記事を公開した。Claude Codeの日常的な承認操作が、データベースパスワードや本番APIキーをGitHubに公開状態で残す——調査で確認されたのは104,185件のファイル中に散らばる2,539件のクレデンシャルだ。悪用や不正アクセスを必要とせず、正規の承認フローだけで発生する点が従来の脆弱性と根本的に異なる。


「一度だけ」のつもりが永続的な漏洩になる仕組み

Claude Codeを使っていると、シェルコマンドの実行前に「このコマンドを実行してもいいですか?」という確認ダイアログが表示される。その選択肢の一つが 「Yes, and don't ask again(はい、今後は確認しない)」 だ。

この承認を選ぶと、コマンドが .claude/settings.local.json に「許可ルール」として保存される。問題は、そのコマンドにデータベースのパスワードやAPIキーが含まれている場合、シークレットがそのままプレーンテキストで記録される点だ。

開発者がデータベースへの接続確認や、APIのデバッグをClaude Codeに頼む場面は日常的だ。Claude Codeが設定ファイルからクレデンシャルを読み込んで実行するコマンドを組み立て、それに対して「今後確認しない」を選ぶ——この普通の作業フローが、シークレット漏洩の起点になる。

AnthropicのGitリポジトリへの対策は一応存在する。初回書き込み時にグローバルな .gitignore へ除外設定を追加する。ただし、この保護はプロジェクトと一緒に配布されず、すでにトラッキング済みのファイルにも適用されず、後からリポジトリ化したフォルダも対象外になる。結果として、.claude/settings.local.json がGitHubにプッシュされる事故が実際に多発している。なお、GitHubのイシューでは、承認済みコマンドへのプレーンテキスト保存が2025年8月の時点で報告されていた。


実態:2,539件のシークレットが公開状態に

セキュリティ企業Apiiroが2026年11月1〜3日にかけて、GitHub上に公開されている 104,185件 の .claude/settings.local.json を調査した。

  • 1,122ファイルに実際のシークレットが含まれ、1,379件の固有クレデンシャルを確認
  • コミット履歴や共有設定ファイル、エージェントのトランスクリプトまで対象を広げると合計 2,539件
  • 影響を受けた組織は 63社、大半がソフトウェア企業

露出したクレデンシャルの内訳:

  • データベースパスワード:379件
  • Supabase のサービスロールキー:122件
  • SSH認証情報(rootパスワードを含むケースあり):43件
  • クラウド認証情報、プライベートキー、パッケージレジストリトークン

具体的には、あるデータベースベンダーの管理者レベルのクラウドキー、本番環境のAzure PostgreSQLパスワード、Squareの本番トークン、医療記録データベースのオーナーパスワードなどが見つかっている。1社はすでに有効なキーが漏洩していたことを確認した。


標準的なシークレットスキャナーでは検出しきれない

既存ツールでの検出率も調査されており、見逃しが無視できない水準だ。

ツール 検出ファイル数(1,122件中)
Gitleaks 564件
TruffleHog 643件
どちらも未検出 215件

PGPASSWORD=、sshpass -p、リクエストヘッダー内に埋め込まれたパスワードは、プロバイダー発行のAPIキーのような明確なフォーマットを持たないため、パターンマッチングが効きにくい。

また、GitHubにプッシュしなかった場合でも、ローカルに平文で保存されていること自体がリスクになる。npmのサプライチェーン攻撃の事例では、攻撃者がTruffleHogを使って開発者のローカルファイルからクレデンシャルを探し出す手法がすでに確認されており、エージェントの承認ファイルは現実的な攻撃対象となりうる。

なお、この問題はプロンプトインジェクションや不正アクセスを必要としない。正規の承認フローだけで発生する点が従来の脆弱性と異なる。


対処方法

Apiiroは以下の対応を推奨している。

まず「削除」より「ローテーション(無効化)」を先に行うこと。 ファイルを消したりGit履歴を書き換えたりする前に、漏洩したクレデンシャルを無効化する。履歴からファイルを消しても、その間にクローンや閲覧が行われていた可能性が残るためだ。

その後の手順:

  1. 現在のファイルとGit履歴で .claude/settings.local.json を検索する
  2. 共有設定ファイル .claude/settings.json にもシークレットが含まれていないか確認する
  3. エージェントの会話ログ、メモリファイル、デプロイメントノートも対象に含める
  4. git rm --cached .claude/settings.local.json でトラッキングを解除し、リポジトリの .gitignore に追加する
  5. コマンド内のリテラルなパスワードをシークレットマネージャーの参照(例:$DB_PASSWORD のような環境変数や AWS Secrets Manager・HashiCorp Vault などのシークレット管理サービス経由の取得)に置き換える

手順5が重要なのは、根本原因がコマンド文字列へのリテラル埋め込みにあるためだ。シークレットマネージャーを参照する形に変えることで、承認ファイルに実際の値が書き込まれなくなり、同じ操作ミスが発生しても漏洩を防ぎやすくなる。

セキュリティチームはエージェント関連フォルダとGit履歴のスキャンに、コマンド埋め込みパスワードへの検出も加えるべきだ。


詳細はClaude Code's "Yes, and Don't Ask Again" Option Can Leak Passwords and API Keys to GitHubを参照していただきたい。