2026年5月20日、GitHubは、攻撃者が約3,800の内部コードリポジトリからデータを盗んだことを確認しました。侵入経路は、GitHubのサーバーのゼロデイ脆弱性ではありませんでした。それは、一人の従業員のノートパソコンにインストールされた、不正なVS Code拡張機能でした。その拡張機能が開発者と同じファイルシステム権限で実行されると、ソースコード、設定ファイル、ワークスペース内のあらゆる認証情報など、手の届く範囲のすべてのものを読み取ることができました。同じ種類の攻撃からAPIキーを保護したいのであれば、その教訓は受け入れがたいものですが、シンプルです。最も弱いリンクは、クラウドであることはめったにありません。それは開発者のマシンであり、その上で動作するツールです。
TL;DR(要するに)
侵害されたIDE拡張機能や流出したリポジトリからAPIキーを保護するには、開発ツールが読み取れる場所にアクティブな認証情報を保存するのをやめてください。シークレットをソースコードから、そしてコミットされた.envファイルから排除してください。.gitignoreは便宜のためのものであり、セキュリティ制御ではないと認識してください。すべてのキーを単一の環境にスコープし、有効期限の短い最小権限の認証情報を使用し、定期的にローテーションしてください。Apidogのようなツールは、API認証情報をリポジトリやワークスペースに散らばったプレーンテキストではなく、ローカルのみの値を持つ環境変数に保持することで役立ちます。
なぜGitHubの侵害はすべての開発者にとって警鐘なのか
GitHubのインシデントは、教科書通りのサプライチェーン攻撃のようです。TeamPCPとして追跡されている脅威グループは、npm、PyPI、PHPエコシステム全体でパッケージをトロイの木馬化してきた経緯があります。今回は、悪意のあるペイロードがVS Code拡張機能に乗って侵入しました。TechCrunchの報道によると、攻撃者は約3,800の内部リポジトリからデータを持ち出し、現在アンダーグラウンドフォーラムで5万ドル以上でデータセットを販売しています。GitHubは、これらの内部リポジトリの外に保存されている顧客データが影響を受けた証拠はないと述べており、調査は継続中です。
ここで一時停止して考えてみてください。VS Code拡張機能は単なるコードです。それをインストールすると、ユーザー権限でエディタプロセス内で実行されます。ファイルを一覧表示し、開いて内容を読み取ることができます。ファイルの変更を監視することもできます。外部ネットワークリクエストを行うこともできます。これらはどれも脆弱性ではありません。これは拡張機能モデルが設計通りに動作していることを示しています。ほとんどの拡張機能は、その役割を果たすためにファイルアクセスを必要とします。問題は、悪意のある、または侵害された拡張機能が、見つけたものを何でも収集するためにまったく同じアクセス権を使用することです。
何を見つけるのでしょうか?典型的なプロジェクトでは、多くのものを見つけます。リポジトリのルートにある.envファイル。config/secrets.yml。削除するつもりだった簡易テストスクリプト内のハードコードされたトークン。~/.aws/credentialsにあるAWS認証情報。認証トークンを含む.npmrc。SSHキー。TeamPCPグループは、「Mini Shai-Hulud」npmワームキャンペーンの背後にいるのと同じ攻撃者であり、感染したマシンから開発者、CI/CD、クラウド、およびAIツール関連の認証情報を収集しました。パターンは一貫しています。開発者のボックスでコードを実行させ、認証情報らしきものをすべて探し出すのです。
これは種類としては新しいものではなく、その知名度においてのみ新しいものです。私たちはVercel侵害から得られたAPIセキュリティの教訓の分析で同様の露出パターンについて書き、サプライチェーンのメカニズムはnpmサプライチェーンセキュリティガイドで取り上げた内容と密接に一致しています。GitHubのインシデントは、より大きな名前がついただけの同じ話です。したがって、今日問うべき質問は直接的です。もし今あなたのエディタで悪意のある拡張機能が実行されたら、何が持ち去られるでしょうか?
ハードコードされたキーとコミットされた.envファイルは常にある負債である
ほとんどの認証情報漏洩は巧妙なものではありません。開発者が「とりあえず」コードにキーを貼り付けて忘れてしまったり、.envファイルが誤ってコミットされてしまったりするものです。どちらも、リポジトリに無期限に残る負債を生み出します。
ハードコードされたキーは明白な過ちです。このようなコードを見たことがあるでしょう。
import requests
# paymentsエンドポイントのクイックテスト
STRIPE_KEY = "sk_live_51Qk2mNExampleKeyDoNotShipThis"
response = requests.post(
"https://api.stripe.com/v1/charges",
auth=(STRIPE_KEY, ""),
data={"amount": 2000, "currency": "usd", "source": "tok_visa"},
)
print(response.json())
そのsk_live_キーは今やファイルの一部です。任意の拡張機能が読み取れるあなたの作業ディレクトリにあります。もしファイルがコミットされると、後でその行を削除しても、キーはあなたのGit履歴に永遠に残ります。リポジトリをクローンする人や、それをスキャンするツールは、誰でもそのキーを入手できます。
.envファイルが解決策となるはずです。その考え方は妥当です。シークレットをコードから切り離し、実行時にロードします。実際の.envは次のようになります。
# .env (実行時にロードされ、出荷されることを意図しない)
DATABASE_URL=postgres://app_user:Zk7%2BqN9wLx@db.internal:5432/payments
STRIPE_SECRET_KEY=sk_live_51Qk2mNExampleKeyDoNotShipThis
OPENAI_API_KEY=sk-proj-aB3dEf9hKlMnOpQrStUvWxYz1234567890
AWS_ACCESS_KEY_ID=AKIA4EXAMPLE7QRSTUVW
AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
JWT_SIGNING_SECRET=8f2a91c4e7b6d3508f2a91c4e7b6d350
これはハードコーディングよりも優れています。しかし、何が変わっていないかに注目してください。そのファイルは依然としてあなたのワークスペースにプレーンテキストで存在し、エディタが実行するすべてのプロセスによって読み取り可能です。悪意のある拡張機能は、シークレットがapp.pyにあるか.envにあるかを気にしません。どちらもファイルです。どちらもfs.readFileSync一つで読み取れます。.envパターンは、ファイルが一度もコミットされない場合にのみ「Git履歴内のシークレット」問題を解決し、「侵害されたローカルツール」問題にはまったく対応しません。
コミットされた.envは最悪の結果です。これは驚くほど一般的です。開発者がプロジェクトに.envを追加し、そこに実際のキーを書き込み、最初のコミットの前にそれを無視することを忘れてしまうことがあります。あるいは、チームメイトがリポジトリをクローンし、.env.exampleを見てそれを.envにコピーし、本番キーを記入し、その後のgit add .でそれが取り込まれてしまいます。その結果、本番環境の認証情報が、公開される可能性のある、ミラーリングされる可能性のある、あるいはGitHubのような侵害に巻き込まれる可能性のあるリポジトリの共有履歴に残ってしまいます。リポジトリ漏洩の側面については、APIドキュメントとGitリポジトリのセキュリティに関する補足記事でさらに詳しく解説しています。
.gitignoreはセキュリティ制御ではない
この誤解は非常に広まっているため、このセクションを設ける価値があります。.gitignoreに.envを追加することは、ドアに鍵をかけるような感覚ですが、そうではありません。それは「これを拾わないでください」と書かれた付箋のようなものです。
.gitignoreが実際に何をするかを見てみましょう。それは、git addを実行したときに、パターンに一致する追跡されていないファイルをGitにスキップさせるものです。その範囲はこれだけです。セキュリティ上重要な3つの失敗モードがあります。
- すでに追跡されているファイルには何もしません。 もし、無視ルールを追加する前に
.envが一度コミットされていた場合、Gitはそれを追跡し続けます。無視ルールは黙って上書きされます。git rm --cached .envを実行してその削除をコミットする必要がありますが、シークレットはすべての過去のコミットに残っています。 - ディスク上のファイルには何もしません。
.gitignoreはGitの指示です。.envファイルは、引き続き作業ディレクトリにプレーンテキストで存在します。悪意のあるVS Code拡張機能はGitインデックスではなくファイルシステムを読み取ります。あなたの無視ルールはそれには見えません。これがGitHub型の攻撃にとって最も重要な失敗モードです。 - 一つのミスでバイパスされる可能性があります。
git add -f .envは無視ルールを無視します。エディタのソース管理UIを介してファイルを追加する場合も同様です。パターンを繰り返さないサブディレクトリ内の別の.gitignoreも同様です。
最初の点について、ご自身で確認できます。もしシークレットがコミットされた可能性があると思ったら、このコマンドで分かります。
# 現在「無視されている」場合でも、そのファイルを触ったすべてのコミットをリスト表示
git log --all --full-history --oneline -- .env
# 履歴に残っている実際のシークレット値を確認
git log -p --all -- .env | grep -iE "key|secret|token|password"
もしこれで何か返ってきた場合、リポジトリが公開された瞬間に認証情報は侵害されています。解決策はより良い無視ルールではありません。解決策はキーをローテーションし、git filter-repoのようなツールで履歴からファイルを削除することです。より根本的な解決策は、アクティブな認証情報がそもそもファイル内に存在しないようにすることです。
.gitignoreは依然として使用する価値があります。正直な間違いを防ぎ、差分をきれいに保ちます。しかし、攻撃者が尊重する境界線だと誤解しないでください。それは衛生であり、防御ではありません。
スコープ、分離、短縮、ローテーション:被害範囲を縮小する4つの習慣
認証情報が絶対に漏洩しないことを保証することはできません。しかし、漏洩した認証情報がほとんど無価値であることを保証することはできます。この4つの習慣がその大部分を担います。
シークレットを環境にスコープする
漏洩したキーは、システム全体ではなく、一つのものだけを解除するようにすべきです。最も一般的なスコープ設定の失敗は、開発、ステージング、本番環境で同じAPIキーを使用することです。なぜならそれが簡単だからです。そのキーが漏洩すると、すべての環境が一斉に危険にさらされます。
各環境に独自の認証情報を付与してください。ローカルマシンでは、サンドボックスプロジェクトとテストデータにアクセスできる開発キーを使用します。ステージングではステージングキーを使用します。本番環境では、厳密に一箇所に存在し、決してノートパソコンにコピーされない本番キーを使用します。もし開発キーが侵害された拡張機能を介して漏洩した場合、攻撃者は偽の顧客データがあるサンドボックスに到達するだけです。それは迷惑なことであり、インシデントではありません。
環境を適切に分離する
環境分離とは、3つの異なるキー値以上のものです。それは、環境が互いに到達できないことを意味します。開発データベースは、本番のリードレプリカではなく、異なるデータベースです。ステージングの支払いプロバイダーはプロバイダーのテストモードであるため、漏洩したステージングキーで実際に料金が請求されることはありません。ツールや人間が、1つの変数を切り替えるだけで「開発」設定を本番データに向けることができないようにすべきです。
分離が真に実現されていれば、「このキーはどの環境から来たのか?」という質問には明確な答えがあり、その答えによって漏洩の深刻度が正確にわかります。
最小権限の短命なキーを使用する
盗まれたキーがどの程度の損害をもたらすかは、2つの特性によって決まります。
権限。 キーは、そのタスクに必要な最小限の権限セットを持つべきです。公開されている製品カタログを読み取るフロントエンドビルドには、その単一のリソースにスコープされた読み取り専用キーが必要です。書き込みアクセス権も、請求アクセス権も、もちろん管理者権限も必要ありません。ほとんどのAPIプロバイダーは、スコープされたキーや細粒度トークンをサポートしています。GitHub独自の細粒度パーソナルアクセストークンは良いモデルです。トークンの種類を検討している場合、APIキーとOAuthの比較記事では、有効期限の短いOAuthトークンが静的キーを完全に上回る場合について解説しています。
寿命。 1時間で期限切れになるキーは、魅力のない標的です。攻撃者が盗まれたデータセットを購入し、あなたのキーにたどり着く頃には、それはもう無効になっています。永久に有効な静的キーはその逆です。誰かが気づくまで機能し続け、それは何ヶ月も続くことがあります。オンデマンドで発行される短命トークンを優先してください。長寿命のキーが避けられない場合は、ワークフローが許容する最短の有効期限を設定してください。
パニック時ではなく、スケジュールに基づいてローテーションする
ローテーションとは、古い認証情報が機能しなくなるように、その値を変更することです。ほとんどのチームは、侵害後に慌てて、ストレス下でローテーションを行います。それは、ローテーションプロセスが文書化されていないことを知る最悪のタイミングです。
代わりに、カレンダーに基づいてローテーションしてください。認証情報の種類ごとに間隔を設定します。高権限の本番キーは毎月、リスクの低いキーは四半期ごとなどです。定期的なローテーションには2つの効果があります。1つは、今日盗まれたキーが次のサイクルで機能しなくなるため、まだ検出されていない漏洩の有効な寿命を制限することです。もう1つは、すべての消費環境で値を更新するという仕組みが、常に練習されて退屈なものになることです。実際のインシデントが発生したとき、ローテーションはあなたが50回押したボタンであり、火災訓練ではありません。より詳しい内容については、APIキー管理ツールのまとめをご覧ください。
認証情報をワークスペースに散乱させず、Apidogの環境変数に保持する
正直な話をしましょう。Apidogは独自のVS Code拡張機能とMCPサーバーを提供しています。ここで主張したいのは、「私たちのツールはGitHubを襲った攻撃クラスに免疫がある」ということではありません。クライアント側のツールにそんなものはありません。ここで議論したいのは、あなたのシークレットがどこに存在し、あなたのマシン上の何かが不審な動作をしたときに、それらがどれだけ露出されるかということです。
現実的なシナリオを考えてみましょう。あなたは一日中APIを構築しテストしています。ベアラートークン、APIキー、データベース接続文字列が必要です。デフォルトの行動は、クライアントが使用できるようにそれらを.envファイルまたはスクリプトにドロップすることです。これにより、アクティブな認証情報がワークスペース内のプレーンテキストファイルに置かれ、まさに悪意のある拡張機能がスクレイピングする対象となります。Apidogの環境システムは、これらの値がどこに格納されるかを変えます。
プレーンテキストファイルではなく環境変数を使用する
Apidogでは、認証情報をリポジトリ内のばらばらのテキストとしてではなく、環境変数として保存します。リクエストはAuthorizationヘッダーの{{access_token}}のように変数名で参照し、Apidogが送信時にそれを解決します。リクエスト定義のヘッダーはBearer sk-proj-aB3dEf...ではなく、Bearer {{access_token}}と読み取られます。実際のシークレットは、プロジェクトルートの.envファイルに読み取られるのを待って存在しているわけではありません。
これは、.envがハードコーディングに勝るのと同じ理由で重要であり、さらに一歩進んだものです。認証情報はもはやソースコードの隣にあるファイル内のプレーンテキスト行ではありません。それはAPIクライアント内の管理された値であり、間接的に参照されます。
ローカル値はシークレットをマシンに保持する
Apidogは、各変数について2種類の値の間に意図的な境界線を引いています。Apidogのサーバーに同期され、チームに表示される共有(または初期)値があります。そして、あなたのマシンに残り、決してアップロードされないローカル(または現在の)値があります。公式のガイダンスは明確です。トークンやパスワードなどの機密データはローカル値に配置し、クライアントから離れないようにしてください。
実際の効果として、プロジェクト構造をクローンしたチームメイトは、access_token、db_passwordなどの変数名と形式は取得しますが、あなたの実際のシークレットは取得しません。各開発者は自分自身のローカル値を記入します。同期されたプロジェクトデータには、誰も本番環境の実際のトークンが一緒に移動することはなく、実際のキーが漏洩するような共有ファイルも存在しません。
環境管理と環境分離
Apidogの環境管理は、前述のセクションのスコープ設定の習慣に基づいて構築されています。開発、ステージング、本番といった個別の環境を定義し、それぞれが独自のベースURLと変数値のセットを持ちます。変数は環境スコープされており、アクティブな環境の値のみが有効になり、環境を切り替えると認証情報セット全体が一度に切り替わります。
これにより、設計上、環境分離が実現されます。あなたのpayment_api_key変数は、開発環境ではサンドボックスキーを保持し、本番環境では本番キーを保持します。それらを切り替えるためにリクエストを編集する必要はなく、環境を切り替えるだけです。値が環境にバインドされているため、開発環境の認証情報が誤って本番環境の呼び出しに混入することはなく、本番環境のシークレットがローカル開発環境に存在する必要もありません。開発環境が漏洩しても、開発用の値が露出するだけで、本番環境は影響を受けません。
厳密な境界線が必要なチーム向け:Vaultシークレット
チームが本番環境のシークレットをAPIクライアントに一切触れさせたくない場合、ApidogのEnterpriseプランは、Vaultシークレット機能を追加します。これはHashiCorp Vault、Azure Key Vault、またはAWS Secrets Managerからシークレットを直接取得します。ApidogはVaultのパスとメタデータのみを保存します。実際のシークレット値はオンデマンドで取得され、ローカルクライアントで暗号化され、プロジェクトを介してチームメイトと共有されることはありません。認証情報の保管場所は専用のシークレットマネージャーに保持され、まさに本番環境の認証情報が置かれるべき場所です。
環境変数ワークフローを試すには、Apidogをダウンロードし、プロジェクトを作成し、環境管理を開き、認証情報をローカルのみの値を持つ環境変数として追加してください。これは数分で完了し、拡張機能が読み取れるプレーンテキストファイルからアクティブなシークレットを排除できます。
正直な注意点です。シークレットをApidogに移行することで、リポジトリやワークスペースに存在するプレーンテキスト認証情報の数が減ります。しかし、それはあなたのマシンを侵害されたツールに対して免疫がある状態にするものではありません。多層防御は依然として適用されます。インストールする拡張機能を監査し、本番環境のキーを最小権限かつ短命に保ち、スケジュールに従ってローテーションしてください。Apidogは「認証情報はどこに保存されるか」という部分を処理します。残りは依然としてあなたの責任です。
結論
GitHubの侵害は明確なシグナルです。攻撃者は、信頼されたツールとプレーンテキストの設定ファイルを持つ開発者のマシンが、どんな本番サーバーよりも柔らかいターゲットであると理解しました。そのマシンを完全に安全にすることはできません。しかし、侵害されたIDE拡張機能や流出したリポジトリが攻撃者の手に渡す情報を最小限に抑えることはできます。
まず一度監査から始めてください。最もよく作業するリポジトリを開き、key、secret、token、passwordを検索してください。.envがGit履歴にあるかどうか確認してください。何が見つかっても、それは露出しているものとして扱ってください。ローテーションし、そのアクティブな値を、不用意なツールが読み取れない場所に移動させてください。Apidogをダウンロードし、次からのAPI認証情報をプレーンテキストファイルではなく環境変数に入れてください。より広い文脈については、GitHub侵害後のセルフホスト型APIツールとAPIキー管理ツールに関する補足記事もぜひお読みください。
よくある質問
VS Code拡張機能は本当に私の.envファイルやAPIキーを読み取ることができますか?
はい、読み取ることができます。VS Code拡張機能は、ユーザーアカウントのファイル権限でエディタプロセス内で実行されます。ディレクトリの一覧表示、ファイルのオープン、および.envファイル、設定ファイル、~/.aws/credentialsのような認証情報ファイルを含む内容の読み取りが可能です。多くの拡張機能は正当にファイルアクセスを必要とするため、これは通常の拡張機能の動作です。リスクは、悪意のあるまたは侵害された拡張機能が同じアクセス権を使用してシークレットを収集することです。これが2026年5月のGitHub侵害のメカニズムです。
.gitignoreに.envを追加するだけでAPIキーを保護するのに十分ですか?
いいえ、十分ではありません。.gitignoreはgit add中に追跡されていないファイルをスキップするようGitに指示するだけです。ルールが存在する前にすでにコミットされたファイルには何もしませんし、シークレットはGit履歴に残り続けます。また、ディスク上のファイルに対しても何もしません。.envファイルは、引き続きワークスペースにプレーンテキストで存在し、あらゆるローカルツールや拡張機能によって完全に読み取り可能です。.gitignoreは正直な間違いを防ぐためのものであり、セキュリティ境界線として扱わないでください。
Git履歴にAPIキーを見つけた場合、どうすべきですか?
たとえリポジトリがプライベートであっても、直ちに侵害されたものとして扱ってください。まずキーをローテーションして、公開された値が機能しないようにします。次に、git filter-repoのようなツールを使用して履歴からファイルを削除し、チームと調整した上でクリーンな履歴を強制プッシュします。最後に、アクティブな認証情報をプレーンテキストファイルから移動させて、同じ漏洩が二度と起こらないようにします。継続的なプラクティスについては、APIキー管理ツールガイドをご覧ください。
ApidogにAPIキーを保存すると、露出はどのように減りますか?
Apidogでは、認証情報を環境変数として保存し、リクエスト内で名前で参照できるため、リテラルなシークレットがリポジトリ内のプレーンテキスト.envファイルにそのまま存在することはありません。各変数は、あなたのマシンに残り、サーバーやチームメイトに決して同期されないローカル専用の値をサポートしており、ドキュメントではトークンやパスワードをそこに保管することを推奨しています。環境スコープされた変数により、開発環境と本番環境の認証情報も分離されます。これにより、ツールがスクレイピングできるファイル内に存在するアクティブなシークレットの数が減りますが、あなたのマシンが侵害されたツールに対して免疫を持つわけではありません。
ApidogもVS Code拡張機能を持っていますが、それはリスクですか?
はい、ApidogはVS Code拡張機能とMCPサーバーを提供しています。この記事の要点は、どのツールもサプライチェーン攻撃に対して免疫があるということではありません。クライアント側のツールには免疫はありません。重要なのは、シークレットがどこに存在するのかということです。認証情報をローカル専用の値を持つ環境変数、またはVault連携に保持することで、Apidog自身の拡張機能を含む、マシン上のツールが侵害された場合に露出するプレーンテキストキーの数が減ります。多層防御、拡張機能の監査、最小権限、そしてローテーションは依然として適用されます。
APIキーのスコープ設定とローテーションの違いは何ですか?
スコープ設定は、キーができることと適用される範囲を制限します。開発キーはサンドボックスのみにアクセスし、読み取り専用キーは書き込みができません。ローテーションは、古い値が機能しなくなるように、キーの値をスケジュールに基づいて変更することです。スコープ設定は、漏洩したキーが引き起こす損害を縮小し、ローテーションは、漏洩したキーが有用である期間を縮小します。両方とも必要です。これらを併用することで、盗まれたキーはほとんど何も解除できず、すぐに期限切れになります。
APIキーはどのくらいの頻度でローテーションすべきですか?
インシデント後だけでなく、固定されたスケジュールに基づいてローテーションしてください。合理的な基準としては、高権限の本番環境の認証情報は毎月、リスクの低いキーは四半期ごととし、リスク許容度やコンプライアンスルールに合わせて調整します。定期的なローテーションは、まだ検出されていない漏洩の有効期間を制限し、ローテーションプロセスを十分に練習された状態に保つため、実際のインシデントが発生しても慌てることなくルーティンとして対処できます。
本番APIキーは開発者のノートパソコンに置かれるべきですか?
理想的には、いいえ。本番環境の認証情報は、可能な限り少ない場所に存在すべきであり、通常は専用のシークレットマネージャーと本番ランタイムに置かれ、開発者のマシンにコピーされるべきではありません。開発者は、非本番データにスコープされた開発用またはステージング用の認証情報に対して作業すべきです。もしノートパソコンが侵害されても、攻撃者は顧客の実システムではなくサンドボックスに到達するだけです。Apidogの環境分離とVault連携は、本番の値をローカル開発環境から遠ざけることで、この原則をサポートします。
