Claude Codeの許可設定から認証情報2,539件がGitHubに漏えい

GitHub上の1,994リポジトリで認証情報2,539件

影響を受けた組織は63にのぼり、そのうち1社は流出したキーが実際に有効だったと認めています。 セキュリティ企業Apiiroが2026年11月5日に公表した調査対象は、AIコーディング支援ツール「Claude Code」が作る設定ファイルです。このファイルから、データベースのパスワードやクラウドキーが公開GitHubで大量に見つかりました。

見つかった場所は、Claude Codeがプロジェクトごとに作る個人用の設定ファイル「settings.local.json」です。今あるファイルに加えて、過去のバージョン、チームで共有する設定ファイル、エージェントとの会話記録まで集計すると、異なる認証情報2,539件が1,994リポジトリで見つかりました。

63組織は規模もさまざまで、多くはソフトウェア企業です。データベース企業が自社で使う管理用のクラウドキーや、本番のAzure Postgresのパスワード、医療記録アプリが使うデータベースの所有者パスワードも含まれていました。Apiiroは11月2〜3日に各組織へ報告しています。

設定ファイル10万件超のうち1.1%に認証情報が残る

Apiiroは11月1〜3日にGitHubのコード検索を使い、ファイルの大きさで検索を区切りながら全件を集めています。その結果、公開GitHub上のsettings.local.jsonは10万4,185件あり、そのうち1,122件から、重複を除いて1,379件の認証情報が見つかりました。

1,379件の内訳は、OpenAIやAWSのようにサービス固有の書式を持つキーが636件、公開されたホストと同じ行に記載されたパスワードやトークンが743件です。

認証情報が含まれている割合は、許可ルール(Claude Codeが確認なしで実行してよいコマンドの一覧)が増えて大きくなったファイルほど高くなります。8KBを超えるファイルでは10件に1件の割合でしたが、500バイト未満では500件に1件を下回りました。

ファイルは長いあいだ公開されたままです。認証情報が見つかったリポジトリでは、ファイルを初めてコミットしてから11月2日までの日数が、中央値で217日にのぼります。118リポジトリでは、最初のコミットが1年以上前でした。

データベースのパスワードが379件と最も多い

settings.local.jsonで見つかった値は、1/3以上がデータベースに直接つながるパスワードとSupabaseのservice-roleキーでした。 Supabaseはデータベースや認証の機能をまとめて提供するクラウドサービスで、そのアカウントトークン103件はアカウント内の全プロジェクトを操作できるものです。

settings.local.jsonで見つかった、認証情報の主な種類(異なる値1,379件の内訳)

種類 件数
データベースのパスワード 379件
Supabaseのservice-roleキー 122件
Supabaseのアカウントトークン 103件
SSHのログイン情報 43件
GitHub・GitLab・npmのトークン 42件
AWSのキー 23件
秘密鍵 6件

残りの多くは、外部サービスのAPIトークンとAIモデルのキーです。SSHのログイン情報43件はいずれも公開サーバー向けで、一部はsshpassのコマンドに入ったrootのパスワードでした。

Apiiroが11月5日に公開した英語の調査記事。見出しの下に、公開GitHubの1,994リポジトリで認証情報2,539件を見つけたという要約が記されている
Apiiroの調査記事の冒頭。要約の段落に、見つかった認証情報の件数とリポジトリの数が書かれています。Apiiro
"Apiiro research found 2,539 real secrets in 1,994 public GitHub repositories: database passwords, cloud keys, API tokens, SSH root logins." / "1,122 files (1.1%) hold a real secret: a key in a known provider format, or a password or token next to a public host." / "More than a third open a database directly: 379 database passwords and 122 Supabase service-role keys." — 冒頭の要約と「How many」の節より
公式情報を見る →

許可したコマンドは認証情報ごと設定ファイルに保存

Claude Codeで許可する操作が、認証情報をファイルへ残す原因です。つまり、このファイルがコミットされると、値はGitHubで誰でも読める状態になります。 認証情報が見つかり、変更履歴をたどれた1,105リポジトリのうち539では、Claudeが共同作成者に入ったコミットがファイルを書き換えていました。

Claude Codeは、Bashコマンドを実行する前にユーザーへ許可を求める仕様です。ここで「Yes, and don't ask again」を選ぶと、承認した内容がsettings.local.jsonに書き込まれ、次からは同じコマンドを確認なしで実行します。Apiiroによると、このファイルをコミットしない指定がリポジトリに無いため、他のコードと一緒にコミットされていました。

チームで共有するためにあえてコミットする設定ファイル「settings.json」でも、7万6,011件のうち298件に認証情報が残っていました。こちらも多くは、許可ルールに入ったコマンドの中です。

承認したコマンドの文字列がそのまま許可ルールになる

データベースの確認などを頼むと、Claude Codeは設定ファイルから読んだ認証情報を入れたコマンドを提案するため、許可すると値まで許可ルールに書き込まれます。 値を含めるのは、認証情報が無ければコマンドを実行できないからです。

開発者のPCには、設定ファイルに書いたデータベースの接続文字列や、.envに置いたAPIトークンがあります。ステージング環境でログインに失敗する原因を調べるよう頼むと、Claude Codeが提案するコマンドにはその値が入ります。

保存されるのは、コマンドの型ではなく文字列そのものです。PGPASSWORD=の後ろにパスワードを付けたpsqlのコマンドを許可すれば、パスワードを含む1行がそのままファイルに残ります。

Apiiroは最新のOpus 5.5とFable 5.1でも同じことが起きると確認し、モデルではなくClaude Code自体の動作だとしています。比較対象は、ドキュメントで確認した16のコーディングエージェントです。そのうち、承認したコマンドを丸ごとプロジェクトのファイルへ書く仕様がデフォルトなのは、Claude Codeだけでした。

gitの除外設定はPCごとで、リポジトリ側には書かれない

Claude Codeにも、settings.local.jsonをコミットさせない仕組みが備わっています。ただし、Claude Codeが登録するgitの除外は、別のPCでクローンしたリポジトリや後からgitを始めたフォルダでは適用されず、ファイルがそのままコミットされます。

公式ドキュメントによると、Claude Codeはこのファイルを初めて書くとき、まだgitの除外対象でなければ、そのPCの全リポジトリに効く除外ファイルへファイル名を書き加えます。登録先はgitの設定core.excludesFileが指すファイルで、未設定なら、ホームフォルダ内にあるgit設定フォルダのignoreです。

この登録はそのPCだけに適用され、リポジトリの.gitignoreには書かれません。除外対象にならないのは、次の3つです。

  • 後からgitリポジトリになったフォルダ
  • 別のPCでクローンしたリポジトリ
  • すでにコミットされたファイル

Claude Code以外でファイルを作成した場合は、グローバルな除外にも登録されません。そのときは、.gitignoreへの追記が必要です。許可の仕組みとautoモードの関係は、別の記事で解説しました。

Claude Codeの公式ドキュメントの設定ファイルのページ。設定ファイルの種類と、それぞれが誰に効くかの説明が並んでいる
Claude Codeの設定ファイルを説明する公式ページ。どの設定ファイルが誰に効くかを表で示しています。Claude Code Docs
"When Claude asks permission to run a Bash command and you choose “Yes, and don’t ask again”, Claude Code saves that permission approval here as an allow rule." / "Claude Code adds it to your global git excludes the first time it writes the file, so it stays out of your commits" — 設定ファイルの種類の説明より
公式情報を見る →
"This is Claude Code's own behavior, not the model's: it happens with Anthropic's latest models too, and we reproduced it with Opus 5.5 and Fable 5.1." / "It doesn't cover a folder that becomes a repo later, a clone on another machine, or a file someone already committed." / "In 539 of the 1,105 repos with a real secret that we traced, a commit co-authored by Claude changed the file." — 「How a secret ends up in a settings file」の節より
公式情報を見る →

検査ツール2種でも215件を検出できず

Apiiroは、ファイルから認証情報を探す無料の検査ツールとして広く使われているgitleaksとTruffleHogを、10万4,185件のファイルすべてにかけました。ところが、2種をかけても、認証情報を含むファイルのうち215件はどちらにも検出されませんでした。

認証情報を含む1,122件のうち、gitleaksが検出したのは564件、TruffleHogは643件です。

過去にコミットされたファイルには、今のファイルに無い認証情報が509リポジトリで734件残っていました。多くは、ファイルを削除した後のリポジトリです。74リポジトリから複製された211のフォークにも、同じ値がそのまま残っています。

コマンド内のパスワードは形式から見分けにくい

キーには、サービス固有の接頭辞と長いランダムな文字列という目印が付いています。ところが、検査ツールはサービスごとに異なるキーの書式を探すため、PGPASSWORD=やsshpass -pに続けて打ち込んだパスワードは検出対象に入りにくくなります。

mysql -pの後ろやcurlのBearerヘッダーに入れたパスワードも同じで、接頭辞のような目印が無く、コマンドの中では普通の単語と変わりません。2種のツールは、その多くを見逃していました。

Apiiroは、コマンドにパスワードを打ち込む書き方がsettings.local.json以外にも現れると指摘しています。エージェントの会話記録は2,523件のうち87リポジトリの120件に、引き継ぎや配布のメモは2,095件のうち33件に認証情報がありました。キーの書式だけを探す検査では、どちらの記録に入ったパスワードも見逃されやすくなります。

今も使えるかは未検証で、Anthropicの見解も出ていない

2025年8月以降、Claude CodeのユーザーはGitHubのissue4件でこの動作を報告していましたが、Anthropicの返信は無く、11月8日時点で今回の調査への見解も出ていません。

(追記)2026年11月9日、Claude Code責任者のBoris Chernyは「防止策を検討している」と述べ、秘密情報のスキャン機能などを検討していると報じられました(TechTimes報道)。 同日時点で修正版は公表されていません。 4件のうち3件は、自動で閉じられています。

Apiiroは、見つけた値でログインを試すことも、接続先にアクセスすることもしませんでした。

判定対象は、サービス固有の書式に合うキーと、公開されたホストと同じ行にあるパスワードやトークンです。仮の値や初期パスワード、ローカルのホスト、期限切れのトークンは、まず規則で除外します。残った2,774件はLLMが基準に沿って確認し、規則でもLLMの確認でも認証情報と判定された値だけを2,539件として数えています。ただし、報告を受けた1社は流出したキーが有効だったと認めました。

"Of the 1,122 files with a real secret, gitleaks flagged 564 and TruffleHog 643; 215 were flagged by neither." / "The gap is passwords inside commands." / "No credential was used or tested, and no host was contacted." / "None got a reply from Anthropic, and three were closed automatically as inactive or duplicate." — 「What secret scanners miss」「Prior work」「Method and limits」の節より
公式情報を見る →

Claude Codeを利用する開発者と管理者が確認すること

一度コミットされた値は、ファイルを削除しても複製や過去のバージョンから読める状態です。したがって、開発者はファイルと履歴を確認して認証情報を無効化・再発行し、管理者はエージェントの設定ファイルを雛形と検査対象に加えます。

JPCERT/CCは2026年10月の注意喚起で、他のシステムの侵害で盗まれたAPIキーが攻撃に使われる場合があるとしています。GitHubに上がった許可ルールの認証情報も、すでに誰かに読まれた前提で対処しましょう。

開発者として:許可ルールに残った認証情報を削除

認証情報が見つかったら、ファイルの削除より先に無効化と再発行を進め、そのあとでファイルと許可の仕方を点検します。 許可ルールに残るのは打ち込んだ文字列なので、渡し方を変えれば同じ形では残らなくなります。

settings.local.jsonとgitの履歴を確認

現在は削除済みのファイルも、gitの履歴に一度でも入っていれば、フォークとクローンにも同じ値が残っています。まず、組織のGitHubでsettings.local.jsonとsettings.jsonを検索します。今は見つからないリポジトリでも、過去にコミットされていないかを履歴から確認しましょう。

一度もコミットしていない場合も、PCにあるsettings.local.jsonを開いて許可ルールの一覧を読んでください。パスワードやトークン、キー、接続文字列を含む行があれば削除します。

PGPASSWORD=やsshpass、Bearerなどの書き方と、AWSやGitHubが使うキーの接頭辞で検索すると、該当する行を見つけやすくなります。非公開のリポジトリでも、追跡されていれば履歴に値が残るため、同じ確認が欠かせません。

見つかった認証情報は削除より先に無効化して再発行

ファイルを削除しても、値はgitの履歴やフォーク、クローンに残り、使える状態のままです。ファイルが一度でも保持したパスワード・トークン・キーは、すべて無効にして新しいものへ切り替えましょう。

ファイルの削除や除外の設定は、無効化と再発行が完了してから行います。リポジトリで追跡されているならgit rm --cachedで追跡をやめ、リポジトリ側の.gitignoreにsettings.local.jsonを加えましょう。リポジトリに書いた除外であれば、別のPCでクローンしても効果があります。

認証情報は環境変数で渡し、許可ルールに値を残さない

コマンドに$DB_URLのような環境変数の名前だけを書けば、許可ルールに残るのは名前だけで、値は残りません。値そのものは、普段使っているシークレットの管理ツールから環境変数へ読み込みます。

許可の仕方も見直しましょう。Apiiroは、個々のコマンドを文字列のまま許可するのではなく、Bash(npm run:*)のように型で許可する方法を勧めています。型で書いた許可ルールには、個々の引数が入りません。

JPCERT/CCのセキュアコーディング規則MSC18-Cは、プログラム内に機密情報をハードコードしないよう定めています。ハードコードすると、開発環境が安全だという条件を前提にすることになるからです。許可ルールに書き込まれたパスワードも、ファイルに直接書かれた機密情報に含まれます。

"Rotate every credential the file has ever held. Removing it doesn't clear git history, forks or clones." / "Stop typing secrets into commands. Reference them as $VAR from whatever secrets manager you use, so the rule records $DB_URL, not the secret." / "Approve patterns, like Bash(npm run:*), instead of literal commands." — 「What to do」の開発者向けの項より
公式情報を見る →

管理者として:エージェントの設定ファイルを検査対象に

管理者は、除外をPCごとの設定に頼らず、リポジトリの.gitignoreと検査ツールで防ぎます。 エージェントが使う設定フォルダとメモリーファイルも、.envと同じく認証情報を含むものとして管理しましょう。

組織の.gitignoreの雛形に個人用設定を追加

リポジトリを作るときに使う.gitignoreの雛形へ、settings.local.jsonの行を加えます。雛形に書いておけば、新しく作るリポジトリでは最初からsettings.local.jsonがコミットされません。

すでにあるリポジトリは、雛形を変更しても対象になりません。このファイルを追跡しているリポジトリが無いかを組織全体で検索し、見つかったら開発者側の手順と同じく、無効化を終えてから追跡をやめるよう伝えましょう。

コミット前とCIで、履歴とコマンド内のパスワードも検査

検査ツールの規則に、PGPASSWORD=やsshpass -p、mysql -pに続く文字列とBearerヘッダーを加えておくと、書式の無いパスワードも検出対象になります。対象フォルダは.claude・.cursor・.gemini・.specstoryで、今のファイルだけでなく履歴もさかのぼって検査します。

Apiiroは、検査をコミットの前とCIの両方に組み込むよう勧めています。見つかった値は、実際にアクセスに使える、公開されたホストと同じ行に記載された認証情報から優先して確認しましょう。

APIトークンに有効期限を付け、権限を最小限に

有効期限が短いトークンや権限の狭いトークンなら、許可ルールから流出しても使える期間と範囲が限られます。JPCERT/CCは2026年10月の注意喚起で、APIトークンに適切な有効期限を設定し、長期間有効なトークンを避けるよう勧めています。

APIのユーザーとAPIトークンには、必要最小限の権限だけを付けます。Supabaseのservice-roleキーのような管理用のキーは、開発者のPCで日常的に使うキーと分けておきましょう。

JPCERT/CCが2026年10月8日に公開し、10月23日に更新した注意喚起のページ。国内組織で相次ぐ不正アクセスについての概要が記されている
JPCERT/CCの注意喚起(JPCERT-AT-2026-0030)。国内組織で相次ぐ不正アクセスへの対策を呼びかけています。JPCERT/CC
JPCERT/CCのセキュアコーディング規則MSC18-Cのページ。プログラム内に機密情報をハードコードしないという規則が見出しで示されている
JPCERT/CCのMSC18-C。プログラム内に機密情報をハードコードしないよう定めています。JPCERT/CC
"Make sure the scanner catches passwords inside commands (PGPASSWORD=, sshpass -p, mysql -p, bearer headers), not only provider key formats." / "Triage credentials paired with public hosts first: those are the ones that give access." — 「What to do」のセキュリティ担当向けの項より
公式情報を見る →
"API利用者やAPIトークンには必要最小限の権限のみを付与する" / "APIトークンには適切な有効期限を設定し、長期間有効なトークンの使用を避ける" / "不要となった、または漏えいが疑われるAPIトークンは速やかに無効化できるようにする" — 対策の項より
公式情報を見る →
"プログラム内に機密情報をハードコードしない。" / "機密情報のハードコードは非常に悪いプログラミング作法と考えられている。というのも、開発環境が安全である、という条件を強制するからである。" — 規則の本文より
公式情報を見る →

FAQ

settings.local.jsonをGitHubに上げていなければ、安全ですか?
安全とは言い切れません。このファイルは開発者のPCに平文のまま置かれており、Apiiroは開発者のPCから認証情報をまとめて集めるマルウェアがすでにあると指摘しています。npmパッケージやDockerイメージ、zipファイルに入って外へ出る場合もあるため、コミットしていなくてもファイルを開き、認証情報を含むルールを削除しましょう。
Claude Code以外のAIエージェントでも同じことは起きますか?
Apiiroがドキュメントを比較した16のエージェントのうち、承認したコマンドを丸ごとプロジェクトのファイルへ書く仕様がデフォルトなのは、Claude Codeだけです。ただし、コマンドにパスワードを打ち込む書き方は他のエージェントの記録にも残ります。VS CodeのCopilotでも、自動承認の設定に認証情報が残ったリポジトリが9つ見つかっています。
Anthropicは対応を発表していますか?
11月8日時点で、今回の調査に対するAnthropicの見解は出ていません。(11月9日、Claude Code責任者のBoris Chernyが「防止策を検討している」と述べ、同日時点で修正版は出ていないと報じられました。)公式ドキュメントでは、Claude Codeは初めてファイルを書くときにPCのグローバルなgit除外へ登録するとしています。ただしこの登録はPCごとでリポジトリには書かれないため、リポジトリの.gitignoreへの追加と、認証情報の無効化・再発行はユーザー側で進めましょう。