概要

  • 出来事:GitHub は、2023 年 3 月 20 日の週に、GitHub.com の RSA SSH ホスト秘密鍵が公開 GitHub リポジトリに一時的に露出していたことを発見したと発表した。新しい鍵は 3 月 24 日午前 2 時 30 分(UTC)頃に一時的に提示された後、同社は同日午前 5 時(UTC)頃に鍵を交換した。
  • 境界:このホスト鍵を所持していれば、攻撃者はトラフィックを転換させられ、かつ古い RSA ID をまだ信頼している SSH クライアントに対して、GitHub になりすますことが可能になる。鍵自体は、GitHub のインフラ、顧客リポジトリ、顧客アカウント、ユーザーのプライベート SSH 鍵へのアクセスを許すものではない。GitHub は、悪用されたと考える理由はなく、この公開は GitHub システムや顧客情報の侵害によるものではないと述べた。
  • 運用上のパラドックス:厳格な SSH クライアントは、GitHub の ID が変更された場合に停止するようになっている。その保護的動作が、誰かが新しい鍵を検証して配布するまで、開発者のプッシュ、自動チェックアウト、サブモジュールの取得、ビルド、デプロイを中断させる可能性がある。古い鍵を盲目的に削除したりチェックを無効にすると、実際の攻撃を特定できたかもしれない証拠を捨てて可用性を回復することになる。
  • アカウンタビリティの所見:GitHub は、ホスト秘密鍵の保管、公開に関する防止と検出、ローテーションの実行、正式な通信、サポート対象のactions/checkoutタグの更新を管理していた。顧客は、信頼ストアの在庫、独立した検証、自動化の更新経路、フォールバックトランスポート、継続性計画を管理していた。公開記録は、中程度の影響を与えるセキュリティおよび継続性の事象であったことを示すが、顧客コードが盗まれたり改変されたりしたという結論には至らない。

02:30 UTC: 正しい新しい ID が早すぎる時点で現れる

GitHub の説明の中で最も示唆的な部分は、偶発的な公開そのものではない。それは、正規のインフラが攻撃下にあるインフラのように振る舞った期間である。

GitHub の最高セキュリティ責任者は、2023 年 3 月 23 日に同社のホスト鍵交換のお知らせを公開した。そのお知らせによると、新しい RSA 鍵は、GitHub が変更の準備を進めていた 3 月 24 日午前 2 時 30 分(UTC)頃に一時的に提示された。午前 5 時(UTC)頃、GitHub は GitHub.com での Git 操作に使用されていた古い RSA SSH ホスト鍵を交換した。同社は、この交換がその後 30 分以内に伝播すると予想していた。

古い RSA ホスト ID をピン留めしていたクライアントにとっては、どちらの提示も深刻な警告を引き起こす可能性があった。リモートの識別情報が変更され、誰かが通信を傍受しているかもしれない、厳格なチェックが拒否したというメッセージだ。しかしそのメッセージは、原因がプロバイダの緊急メンテナンスなのか、オペレータのミスなのか、破損した信頼ストアなのか、DNS やルーティングの迂回なのか、あるいは盗まれたホスト鍵を使った攻撃者なのかを伝えなかった。伝えようがなかったのだ。この制御の目的は、説明のつかない ID 変更を「停止」に変換することだった。

したがって GitHub は、ユーザーに対して時間的プレッシャーの下で結果を左右する区別をつけるよう求めていた。古い鍵は退役させるには十分に危険になった。新しい鍵は定義上未知のものだ。修復の目に見える兆候は、脅威の目に見える兆候でもあった。パッチを送信したい開発者や、人の手を介さずにデプロイするよう期待されているビルドランナーは、問題の SSH 接続から得られない第三の事実を必要としていた。すなわち、GitHub の新しい鍵が何であるべきかを示す、独立して認証された表明である。

だからこそ、GitHub が顧客データ侵害を報告しなかったにもかかわらず、この事象はアカウンタビリティの記録に属する。クラウドサービスは、内部システムを稼働させ続ける責任だけを負うわけではない。信頼マテリアル、クライアントの動作、更新義務、緊急時の意思決定を顧客環境に輸出する責任も負う。今回の場合、HTTPS 経由ではサービスは利用可能であり、GitHub の ECDSA および Ed25519 ホスト鍵は変更されなかった。それでも、プロバイダ側の一つの秘密が、グローバルな顧客側の検証タスクを生み出したのだ。

最初の反実仮想はシンプルだ。仮に警告が現れなかったとしたら。自動化されたジョブは変更されたサーバーID を通じて続行され、組織はコードを詐称者を介して送受信したのかどうかを決して知ることができなかっただろう。ジョブの失敗こそが安全な結果だった。継続性の問題は、SSH が慎重すぎることではなかった。多くの組織が、慎重な拒否を検証済みの回復に変える準備された方法を持っていなかったことだ。

何が露出し、何が露出しなかったか

SSH は異なる主張に異なる鍵を用いる。これを混同すると、事象は証拠が許すよりもはるかに深刻か、はるかに小さく聞こえてしまう。

ユーザー鍵やデプロイ鍵は通常、クライアントを GitHub に対して証明する。保持者がアカウントやリポジトリに関連付けられた秘密鍵の制御を実証するのである。ホスト鍵はサーバーをクライアントに対して証明する。GitHub が鍵交換マテリアルに署名することで、クライアントは相手方が GitHub の期待されるサーバーID を制御していると判断できる。SSH トランスポート仕様(RFC 4253)は、トランスポート層での暗号化ホスト認証を、その上のユーザー認証から分離している。GitHub の露出した秘密は、その交換のサーバーID 側にあった。

GitHub は、この RSA ホスト秘密鍵が同社のインフラや顧客データへのアクセスを許すものではないと述べた。また、この露出は GitHub システムや顧客情報の侵害によるものではなく、この鍵が悪用されたと考える理由はないとも述べた。これらは意味のある境界線である。これにより、公開そのものを、攻撃者が GitHub にログインした、プライベートリポジトリを保存状態で読み取った、ユーザーの SSH 秘密鍵を入手した、ブランチを変更した、あるいは Web や HTTPS Git サービスに到達したという証拠として扱うことは除外される。

リスクは条件付きだが現実のものだった。古いホスト秘密鍵を所持する攻撃者は、依然として被害者の経路に偽者を置くか、被害者にそこへ接続させる必要があった。それには悪意ある DNS、経路操作、侵害されたプロキシやネットワーク、欺瞞的なホスト設定、クライアントが既に通過しているインフラの制御などが関与し得る。クライアントが古い RSA ID を GitHub として受け入れた場合、攻撃者は明らかに信頼できるホストとして SSH 接続を終端し、そのエンドポイントに送られた Git リクエストを観察し、プッシュされたオブジェクトを受け取り、偽のリポジトリ内容を提供し、クライアントの設定次第ではより複雑なリレー攻撃や認証情報攻撃を試みることができた。盗まれた鍵はサーバーなりすまし能力を提供したが、ネットワーク上の位置を自動的に提供したわけではない。

また、公開記録は過去に記録された Git トラフィックの遡及的解読を立証するものでもない。現代の SSH 鍵交換は通常、セッション秘密を別個に導出し、ホスト鍵を交換の認証に使用する。GitHub のお知らせはなりすましや盗聴の機会について警告したが、過去のセッションが解読された、悪意あるエンドポイントが見つかった、被害者の接続が特定された、リポジトリの素材が傍受されたとは報告しなかった。

これは規律あるインシデント声明を生み出す。プライベートなサービス認証鍵が公開された。その開示により一部の SSH クライアントに対してサービスになりすます機会が生まれた。GitHub は鍵を交換することでその機会を取り消した。その交換は一部の正しく厳格なクライアントに混乱をもたらした。そして本記事がレビューした限りでは、悪用が実際に行われたことを示す公開証拠はない。潜在的な結果が緊急性を知らせるべきで、観測された侵害として書き換えられるべきではない。

サブセットも重要だ。GitHub は GitHub.com の RSA SSH ホスト鍵のみを交換した。同社のお知らせによれば、ECDSA および Ed25519 ユーザーは対応不要で、HTTPS Git 操作と通常の Web トラフィックは影響を受けなかった。GitHub が維持するSSH フィンガープリントページでは、RSA、ECDSA、Ed25519 のフィンガープリントと完全な公開鍵エントリが個別に公開されている。アルゴリズムを特定せずに「GitHub の SSH 鍵が変わった」と言う組織は、まだ有効な信頼を不必要に削除し、フォレンジックレビューをより困難にしてしまうだろう。

公開情報から読み取れるタイムライン

この事象は、GitHub が開示した解像度でのみ再構築可能である。欠けている部分は推測の余地ではなく、所見の一部なのだ。

発見前:古い RSA ホスト鍵は有効であり、クライアントから信頼されていた。GitHub は、秘密鍵が出現したリポジトリ、それを所有していたアカウントや組織、ファイルパス、公開した人物やプロセス、正確な露出期間を公的に特定していない。「一時的」とはタイムスタンプではない。認証されていないクローン、フォーク、キャッシュ、検索インデックス、API レスポンス、ログ、サードパーティのミラーがその素材を保持したかどうかは開示されていない。

3 月 20 日の週:GitHub は露出を発見した。お知らせでは、検知が自社のシークレットスキャン、従業員、ユーザー、研究者、あるいは他の自動化された制御によるものかは述べていない。同社は直ちに露出を封じ込め、根本原因と影響の調査を開始したとしている。公開説明では、後のホスト鍵交換以外に、リポジトリアーティファクトの封じ込めに何が含まれていたかは定義されていない。

3 月 24 日午前 2 時 30 分(UTC)頃:一部のクライアントは、準備中に新しい RSA ホスト鍵に遭遇した可能性がある。これは、信頼ストアの変更がおおよそ午前 5 時(UTC)の交換時点より前に外部から可視化されたことを意味するため重要だ。リハーサルされた緊急計画においては、準備中の提示は文書化された期待動作に沿った意図的な互換性ステップであるか、インシデントタイムラインに記録されたデプロイ異常であるかのいずれかだ。GitHub はこれを認めたが、メカニズムは説明しなかった。

およそ午前 5 時(UTC):GitHub は RSA 交換を完了し、伝播に約 30 分を要すると見込んだ。この時点で古い鍵は本物の GitHub.com SSH サービスの認証に使えなくなるはずだった。それにピン留めしていたクライアントは安全側に失敗する(fail closed)可能性があり、変更されていない鍵タイプでネゴシエーションするクライアントは継続できた。HTTPS は代替の Git トランスポートとして利用可能なままであった。

交換直後:GitHub は、ユーザーに古いgithub.comエントリを削除し、新しい公開鍵を直接追加するか、GitHub Meta API から公開鍵を取得し、新しい RSA フィンガープリントを確認するよう促した。また、ssh-keyオプションを付けてactions/checkoutを使用する GitHub Actions ジョブが失敗する可能性があると警告した。GitHub は、アクションのサポート対象タグであるv2,v3,mainを更新中であると述べた。特定のコミット SHA にピン留めされたジョブはこれらのタグでは移動しないため、意図的な更新が必要だった。

公開エンドポイントの状況:現在のREST Meta エンドポイントドキュメントによれば、未認証のGET /metaレスポンスには SSH 鍵のフィンガープリントと完全なホスト公開鍵の両方が含まれる。これはマシンに構造化された情報源を提供する。しかし、インシデント中に特定の組織が新しいレスポンスを信頼すべきかどうかを決定するものではなく、現在のスキーマが 2023 年 3 月に各クライアントが受信した正確なレスポンスを証明するものでもない。

公開された時系列はここで終わっている。レビューした情報源において、GitHub は、公開経路、露出期間、スキャナの挙動、障害が発生した顧客数、古い鍵を使用しようとする試みの観測、永続的な鍵保管の変更などを特定する後のフォレンジックレポートを発行していない。これらの詳細がないことは、GitHub がそれらを調査しなかったことを証明するものではないが、外部者が検証できることを制限する。

警告は、クリアすべきエラーメッセージではなく、意思決定ポイントだった

GitHub の現在のホスト鍵検証トラブルシューティングページは、正しい判断ルールを示している。予期せぬ鍵には、信頼できる情報源からの公式な説明が必要であり、そのような説明がなければ、接続しないことが最も安全な行動だとしている。特に、GitHub のホスト鍵変更は GitHub ブログで発表されると明記し、フィンガープリントのドキュメントを参照するよう指示している。

このルールは、一つの赤いターミナルメッセージを三つの別個のタスクに変える。

第一に、何が起きたかを保存すること。UTC 時刻、ランナーまたはワークステーション、接続先の名前とアドレス、鍵アルゴリズム、提示されたフィンガープリント、コマンド、関連するネットワーク経路を記録する。「GitHub がダウンしている」だけのサポートチケットは、セキュリティ上のシグナルを失わせる。誰かがキャプチャする前に開発者が行を削除してしまうことも同様だ。

第二に、問題の鍵に依存しない経路で検証すること。2023 年 3 月、GitHub は HTTPS ブログのお知らせ、HTTPS ドキュメントページ、HTTPS API エンドポイントを提供した。これらの経路は GitHub の管理下にあったが、古い SSH ホスト鍵ではなく Web PKI を利用していた。一般の開発者にとって、警告のフィンガープリントをお知らせやドキュメントと照合することは、同じ SSH 経路で提示された鍵を受け入れるよりもはるかに優れていた。

第三に、影響を受ける信頼を最も狭い範囲で更新すること。対象のホスト名または管理エイリアスの古い RSA エントリを削除し、承認された代替エントリをインストールし、テストする。known_hostsファイル全体を削除すると、無関係なサービスに対する信頼も破棄される。疑問のあるネットワーク経路からssh-keyscanで鍵を取得してすぐに信頼するのは、単にその経路が言っていることを記録するだけだ。インシデント当時の OpenBSD 7.2 のssh-keyscan マニュアルは、未検証のスキャン出力から known-hosts ファイルを構築すると、中間者攻撃に対して脆弱になると警告している。

運用上の誘惑はStrictHostKeyChecking=noを設定したり、UserKnownHostsFileを使い捨ての場所に向けたりすることだ。それでパイプラインはグリーンになるかもしれないが、問いは「これは GitHub か?」から「ポート 22 に何か応答したか?」に変わる。OpenSSH のクライアント設定マニュアルは、厳格なチェックは変更されたホスト鍵を拒否し、この種のなりすましに対する最大限の保護を提供すると説明している。また、accept-newは未知のホストを受け入れるが、変更された鍵は依然拒否する。どちらの設定も、真正なホスト ID を配布する必要性を取り除くものではない。

この教訓は、すべての開発者が午前 5 時(UTC)に暗号学者にならなければならないということではない。組織が、緊急事態前に暗号上の問いを運用上の問いに変換しておくべきだということだ。どの情報源が信頼できるか、誰が新しいフィンガープリントを承認できるか、どのように配布するか、どのジョブを一時停止すべきか、回復の成功をどう証拠づけるか、といったことだ。

反実仮想 1:露出がスケジュールを強制する前にローテーションする

もし GitHub が 1 か月前に RSA ホスト鍵を計画的な演習としてローテーションしていたらどうなっていたか考えてみよう。

計画的なローテーションなら、将来のフィンガープリントを事前に公開し、複数のホスト鍵アルゴリズムを提示し、管理された信頼ストアを更新し、GitHub Actions のパスを演習し、まだ RSA にピン留めされているクライアントを測定し、定義された重複期間の間は古い鍵を有効なままにしておくことができる。OpenSSH のUpdateHostKeysメカニズムは、サーバーが既に信頼された鍵で認証した後にのみ追加の鍵を学習できる。これは、現在の鍵を廃止する前に次の ID を導入するという、優雅なローテーションのための有用なパターンだ。

秘密鍵露出後の緊急ローテーションは異なる。古い秘密鍵が攻撃者の手に渡っている可能性がある場合、重複期間を長くすることはなりすましの機会を長引かせる。プロバイダは決してローテーションしないと約束することでこの緊張を解決できない。独立して保護された複数のホスト鍵を維持し、クライアントのネゴシエーションを定期的にテストし、安定した検証エンドポイントを公開し、圧縮された失効パスをリハーサルし、どのプロバイダ管理の依存関係が古い鍵を埋め込んでいるかを把握することで、それを軽減できる。

GitHub には既に ECDSA と Ed25519 のホスト ID があり、お知らせによればそれらの鍵のユーザーは影響を受けなかった。これは爆発半径を縮小した。公開記録は、すでにそれらの代替手段を学習していたユーザーやジョブの数、RSA のみだった数、露出前のローテーション演習が緊急パスをテストしていたかどうかを定量化していない。これらの数字は、サーバー側の暗号的多様性と、顧客ベース全体にわたる実際の継続性とを区別するだろう。

実用的なローテーションテストには両端での証拠が必要だ。プロバイダは、秘密素材を開発者ワークスペースにエクスポートせずに代替を生成できること、意図しない早期提示なしにデプロイできること、古い鍵を迅速に失効できること、ブログ、ドキュメント、API、サポート、ステータスメッセージングが一貫性を保つこと、ファーストパーティのクライアントとアクションが更新できることを示せるべきだ。顧客は、予告なしの変更を拒否し、承認された公表済みの変更を受け入れ、各開発者がその場しのぎする必要がないことを示せるべきだ。

重要な指標は「ローテーション完了」ではない。プロバイダの決定から検証済みの顧客回復までの時間であり、人間のワークステーション、永続サーバー、エフェメラルランナー、サードパーティ CI、デプロイアプライアンス、ピン留めされたアクションバージョンに分けて計測する必要がある。サービスのエッジで成功したローテーションが、価値の高いデプロイメントシステムがソースを取得できないままになっている場合、技術的には完了しても運用上は未完了である。

反実仮想 2:検証を意味のあるほど独立させる

ここで、攻撃者が露出した RSA 鍵と、GitHub が変更を発表した時点で顧客のネットワーク上にポジションを持っていたとしよう。顧客は本物の新しい鍵と、依然として信頼されている古い鍵を提示する攻撃者を区別できるだろうか?

3 月のお知らせは、いくつかの有用な事実を提供していた。影響を受けるアルゴリズム、交換後のフィンガープリント、完全な公開鍵、有効時期、変更されていない代替手段、コマンドなどである。GitHub の API はマシン可読なデータを提供した。ドキュメントとブログは HTTPS を使用していた。ほとんどの組織にとって、これらの表面を一つ以上チェックし、完全なフィンガープリントの一致を要求することは、合理的な緊急手順だった。

しかし「独立」には幅がある。ブログ、ドキュメント、API、サポートポータル、サービスは、同じ企業およびドメインのエコシステム内で運営されている。GitHub の公開制御プレーンの広範な侵害は、一度に複数に影響を与える可能性があるが、ここではその証拠はない。より高い保証を必要とする顧客は、自身の設定リポジトリに承認済みフィンガープリントをキャッシュしたり、事前登録されたチャネルを通じて署名付きベンダーアドバイザリを受信したり、別々のネットワークからの情報源を比較するために内部レビュアー2 名を要求したり、信頼できるサプライヤーフィードを使用したりできる。

SSH プロトコルは他の信頼配布モデルも定義している。RFC 4255は SSHFP DNS レコードを規定し、安全な検証チャネルなしに受け入れられたフィンガープリントは接続を脆弱にすると強調している。DNS ベースのロールオーバーは、DNS データが(通常は DNSSEC で)認証されており、クライアントがポリシーに従ってそれを検証する場合にのみ意味がある。フィンガープリントを SSH の警告から未署名の DNS に移すことは、信頼問題を解決するのではなく移し替えるだけだろう。

GitHub の信頼性コミュニケーションは関連性はあるが互換性はない。同社のステータスサイト設計の説明によれば、Git 操作には独立したコンポーネントがあり、顧客はメール、SMS、Webhook でサブスクライブできる。現在のGitHub サポートドキュメントも同様に、顧客をステータスインシデントやサブスクリプションチャネルに誘導している。これらのフィードは運用チームにサービス問題の存在を伝えることができる。しかし、インシデントメッセージが信頼できる鍵の証拠を伝えるかリンクしていない限り、ステータスライト単独では交換されたフィンガープリントを認証できない。

したがって反実仮想テストは具体的だ。ステージングランナーを組織の通常の管理コンソールから切断し、期待される GitHub の RSA 鍵をテスト鍵に置き換え、その応答を観察する。ジョブは停止するか?アラートは提示されたフィンガープリントを保存するか?オンコールエンジニアはそのジョブに依存しない経路で承認済みアドバイザリを見つけられるか?変更を承認する権限を持つ人物の身元はあるか?構成管理はフリートを原子的に更新し、不正な形式のエントリをロールバックできるか?答えが「誰かがウェブを検索して最初のコマンドを貼り付ける」なら、信頼モデルは依然として人間の運に大きく依存している。

反実仮想 3:「一時的」が始まる前に秘密鍵を止める

この事象は公開リポジトリ内の秘密素材から始まったので、合理的な制御レビューではどこで公開が遮断できたかを問う必要がある。ただし、GitHub が提供しなかった答えを仮定してはならない。

インシデントの数週間前の 2023 年 2 月 28 日、GitHub はシークレットスキャンアラートがすべての公開リポジトリで無料で一般利用可能になったと発表した。この発表では、リポジトリ所有者は履歴全体のスキャンを有効にし、プロバイダ通知が不可能な秘密(自己ホスト鍵を含む)についてアラートを受け取れるとされていた。これは、公開リポジトリ管理者向けの製品機能とそのオプトインの性質を示すものだが、問題のリポジトリでこの機能が有効だったか、露出したエンコーディングがサポートパターンに一致したか、GitHub の内部セキュリティに別の制御があったか、スキャンが鍵を発見したかを確定するものではない。

タイミングが重要だ。GitHub はプッシュ保護をすべての公開リポジトリで一般提供したのは 2023 年 5 月 9 日であり、ホスト鍵インシデントの後である。それ以前は GitHub Advanced Security ユーザー向けに存在していた。後の発表は、より強力な制御ポイントを説明している。リポジトリに到達する前に高確信度の秘密を特定し、投稿者に削除するか明示的にバイパスするよう求めるというものだ。5 月の広範な可用性を 3 月に当てはめて読むのは不正確である。

GitHub の現在のサポートパターンリファレンスには、汎用 RSA および OpenSSH 秘密鍵パターンが記載されている。これは有用な 2026 年のベンチマークだが、2023 年 3 月のマッチャーを証明するものではない。秘密ホスト鍵はエンコードされていたり、分割されていたり、暗号化されていたり、ビルド中に生成されていたり、アーカイブに保存されていたり、汎用パターンが見逃す形式で表現されていた可能性もある。シークレットスキャンは一つの層であり、保管設計そのものではない。

より強力な反実仮想は Git の手前から始まる。なぜプロダクションサービスのホスト秘密鍵が、いかなるリポジトリにもコミット可能なコンテキストに存在できたのか?成熟した設計では、プロダクションの秘密鍵操作を署名境界の背後、ハードウェアベースのサービス、または厳格に制御されたデプロイメントメカニズムに保ち、エクスポートを制限し、プロダクション素材が通常のファイルシステムやログに入るのを防ぎ、リポジトリを分類し、ローカル変更とサーバーサイドプッシュをスキャンし、バイパスにはレビューを要求し、確実な露出が確認されたら鍵を自動的に失効させる。

公開されたお知らせは、鍵が通常の保管システムからエクスポートされたのか、安全でない場所で生成されたのか、テスト用にコピーされたのか、自動化から出力されたのか、それが何であるか知る由もない誰かによって公開されたのかを述べていない。その後変更された予防的制御についても特定していない。アカウンタビリティは、この沈黙から正確な根本原因を割り当てることはできない。しかし、プロバイダが保持すべき証拠を特定することはできる。鍵の生成およびエクスポートログ、リポジトリのプッシュイベント、スキャナー結果、アラートルーティング、最初の閲覧とクローンの時刻、封じ込め措置、鍵使用のテレメトリ、キャッシュとフォークのレビュー、失効の決定記録である。

ここには不快なプロダクトレベルの鏡がある。GitHub は顧客が GitHub 上に秘密を公開するのを防ぐための制御を販売し文書化している。自社のホスト鍵が公開 GitHub リポジトリに現れた。これは偽善や製品の失敗を証明するものではない。制御が事象を検出したかもしれないし、そのリポジトリに適用されていなかったかもしれないし、バイパスされたかもしれない。しかし、制御パスの開示が特に価値あるものとなっている。それなしでは、顧客はローテーションを見ることはできても、公開防御が改善されたかどうかを学ぶことはできない。

反実仮想 4:信頼ストアを本番依存関係として扱う

エンタープライズオートメーションはしばしば SSH 信頼を列挙しにくい場所に隠している。ベースイメージ、デプロイメントコンテナ、セルフホストランナー、ベンダーアプライアンス、Jenkins の認証情報、Kubernetes の Secret や ConfigMap、開発者のブートストラップスクリプト、ゴールデンマシンイメージ、ビルドパック、サブモジュール設定、アクションコードである。一部のエントリーはgithub.comを使用し、他は SSH エイリアス、踏み台、解決済みアドレス、ハッシュ化されたホスト名を使用している。状態を維持するランナーもあれば、依然として古い鍵を含むイメージから毎回再構築されるランナーもある。

3 月のインシデントはその不可視性のコストを露呈した。GitHub は特に、ssh-key入力を使用するactions/checkoutジョブが失敗する可能性があると警告した。メンテナンスされているactions/checkoutリポジトリはその理由を文書化している。SSH 認証が選択されると、アクションは秘密鍵を設定し、デフォルトで厳格なホストチェックを有効にし、暗黙的に GitHub.com の公開ホスト鍵を追加する。アクションを更新すると、移動可能なタグに対して埋め込まれた信頼が更新される可能性がある。固定されたコミットにピン留めされたジョブは、レビュー済みの古いコードを実行し続け、古いホスト素材を含むことになる。

これはピニングに対する反論ではない。現在の GitHub のActions オートメーションの保護に関するガイダンスは、移動可能なタグがジョブが実行するコードを変更し得るため、完全なコミット SHA を推奨している。2023 年 3 月において、この完全性制御は継続性のコストを伴った。GitHub はサポート対象タグを中央で修復できたが、SHA ピンされた顧客は新しいコミットをレビューして選択する必要があった。セキュリティ特性は衝突し得る。答えはレビューを維持する更新プロセスであり、可変依存関係への恒久的な切り替えではない。

したがって、エンタープライズの信頼プロセスは信頼マテリアルの台帳を維持すべきだ。ホスト名、サービスオーナー、アルゴリズム、承認済みフィンガープリント、検証元、消費システム、配布方法、最終テスト日、ローテーション連絡先、緊急時フォールバックである。変更はコードレビューされるべきだが、承認パスには緊急レーンが必要だ。中央チームは新しい鍵をステージングし、SSH 経由でカナリアフェッチを実行し、HTTPS と比較し、プロバイダの Meta API にクエリをかけ、その後管理されたクライアントを通じて変更を展開できる。開発者は影響を受けるアルゴリズムを正確に指定し、チェックを弱める指示を含まない短い内部アドバイザリを受け取る。

ログはフォロースルーを支援する。GitHub の現在の組織監査イベントリファレンスは、トランスポートプロトコルフィールドを含むgit.cloneおよびgit.fetchイベントを文書化しているが、Git イベントのアクセスと保持は通常の監査イベントとは異なる。これらの記録はエンタープライズが SSH 利用を推定し、インシデント周辺の活動を特定するのに役立つが、GitHub に到達しなかった失敗した接続を列挙するものではなく、現在のドキュメントがすべての顧客の 2023 年の計画や保持を記述していると仮定すべきではない。クライアントおよび CI ログは依然として必要である。

反実仮想テストは、何かをローテーションする前に、エンタープライズが「GitHub の RSA ホスト鍵が変更された場合、どの本番パイプラインが停止するか?」に答えられるかどうかだ。答えが許容可能なデプロイ停止時間よりも長い場合、信頼ストアは管理されていない本番依存関係である。

CI がフィンガープリントをサービス継続性イベントに変える

人間の開発者は警告を見る。無人のランナーは非ゼロの終了ステータスを返す。この違いが影響の形を変える。

一つのチェックアウトの失敗が、テストの開始を妨げ、リリースアーティファクトのビルドを停止させ、インフラリポジトリが変更を適用するのをブロックし、ソースを待ってデプロイを保留させる可能性がある。プライベートサブモジュールとセカンダリリポジトリは、actions/checkoutに SSH 鍵を供給する一般的な理由であり、他の CI システムは直接git cloneを呼び出す。ホスト鍵チェックは、Git がリクエストされたリポジトリが安全か、緊急か、公開かを判断する前に発生する。影響を受けるすべての操作は、同じ信頼境界で失敗する。

障害は不均一でもあり得る。以前に Ed25519 を学習したラップトップは継続する一方で、RSA にピン留めされた古いアプライアンスは停止する。サポート対象の可変タグを使用している GitHub ホストジョブはプロバイダがタグを更新した後に回復するかもしれないが、イメージが焼き付けられたセルフホストランナーは壊れたままである。一つの地域オフィスは管理された信頼バンドルを通過し、別のオフィスはユーザーごとのファイルに依存するかもしれない。リトライは誤解を招く証拠を生み出し得る。ジョブは 02:30 頃に準備中の鍵に遭遇し、伝播中に再び古い鍵に遭遇し、05:00 以降に新しい鍵に遭遇するかもしれない。

2023 年 3 月 24 日のGitHub コミュニティディスカッションにおける逸話的報告は、ユーザーが変更された鍵と失敗したランナーが正当なものかどうかを判断しようとしている様子を示している。コミュニティ投稿は混乱と運用症状の有用な証拠だが、影響を受けたユーザーの正確な数ではない。GitHub は失敗したジョブ、SSH クライアント、遅延したデプロイメントの分母を公表しなかった。

だからこそ影響は無視できるまたは高いではなく、中程度と評価される。露出した鍵は深刻な潜在的信頼障害を生み出し、緊急交換は世界中の実際のデリバリーシステムを中断させる可能性があった。同時に、開示された事象は一つのホスト鍵アルゴリズムに限定されており、代替の SSH ホスト鍵と HTTPS は利用可能であり、悪用、広範なリポジトリ侵害、長期にわたる GitHub 停止、安全影響、定量化された重大な事業損失を示す公開証拠はない。

最も危険な回復措置は、中程度の中断を無制限のインテグリティリスクに変えることだった。つまり、リリースを進めるためにグローバルにホストチェックを無効にすることだ。より規律あるランブックは、影響を受けるレーンを一時停止し、承認された HTTPS または内部チャネルを通じて新しい鍵を検証し、カナリアを更新し、読み取り専用フェッチと ID テストを実行し、信頼変更をデプロイし、その後失敗したジョブを再実行する。未検証のエンドポイントを介して試みられたプッシュやデプロイは、単にリトライするのではなく、レビューを必要とする証拠として扱われるべきだ。

同じ朝の中小企業バージョン

中小企業はしばしば、リポジトリホスティング、コラボレーション、アイデンティティ、オートメーションスタックを経済的に再現できないために GitHub を利用している。その効率性が意思決定をごく小さなチームに集中させる。ホスト警告を受け取った人物は、製品デリバリー、カスタマーサポート、クラウドインフラ、インシデント対応も担っているかもしれない。

この事象の 2 か月後に公開された CISA の中小企業向け ICT サプライチェーンリスクファクトシートは、この制約から出発している。中小企業は ICT 製品やサービスに依存しているが、専任のリスク管理機能を持たないかもしれない。そのような企業に「フィンガープリントを検証せよ」と言うだけでは必要だが不十分である。唯一のエンジニアがリリースのプレッシャー下にあるときでも機能する、低コストの手順が必要だ。

最小限の実行可能な手順は控えめなものだ。テスト済みの認証情報方法を用いた 2 つ目の Git リモート URL を HTTPS で維持する。ビジネスクリティカルなリポジトリのローカルまたは外部ミラーを維持する。少なくとも 2 人の人物または役割をプロバイダのセキュリティおよびステータス通信にサブスクライブさせる。承認済みのホストフィンガープリントとソース URL を内部ランブックに保存する。組織全体の信頼を変更する前にセカンドチェックを要求する。どの CI ジョブが SSH を使い、どのジョブが HTTPS を使うかを把握する。四半期ごとにチェックアウト障害テストを実施する。

GitHub のリモート管理ドキュメントは、リモートを SSH と HTTPS 間で切り替える方法を説明している。これは 3 月の事象が HTTPS Git 操作に影響しなかったため、有用な継続性オプションである。ただし自動フェイルオーバーではない。HTTPS は独自の認証情報、信頼、プロキシ、最小権限の設定を必要とする。ビルドログに広範な個人アクセストークンを埋め込む急ぎの切り替えは、一つのインシデントを解決するために別のインシデントを生み出す。

リポジトリの可用性にも境界が必要だ。Git は分散型であるため、アクティブなクローンにはプロジェクト履歴が含まれるが、開発者ラップトップは完全な組織バックアップではない。GitHub のリポジトリバックアップガイダンスは、履歴のためにミラークローンを推奨し、異なる方法が異なるメタデータやラージファイルストレージオブジェクトを除外することを警告している。公式git-bundle ドキュメントは、オフライン転送と完全または増分リポジトリバックアップを説明している。どちらのメカニズムも、イシュー、プルリクエスト、Actions 設定、シークレット、パッケージ、ブランチルール、現在のチーム権限を自動的に保存するわけではない。

中小企業にとって、継続性はすべてのプロジェクトに 2 つ目の完全に稼働するフォージを必要としない。ビジネス上の影響に応じたフォールバックの適合が必要だ。デプロイを 4 時間遅らせることができる企業は、検証済み HTTPS フォールバックとミラーだけでよいかもしれない。緊急修正が GitHub に依存するヘルスケアや決済のサプライヤーは、テスト済み外部バックアップ、再現可能なビルドツール、第 2 の承認チャネル、文書化された手動リリースパスを必要とするかもしれない。問題は GitHub が「十分に信頼できる」かどうかではない。企業が本番を変更する能力のどれだけが一つのプロバイダの信頼表明に依存しているかだ。

評価を変え得る証拠

公開記録は交換措置については強固だが、露出のメカニズムについては弱い。

GitHub が報告された時刻に RSA ホスト鍵を交換したことについては高い確信がある。なぜなら同社は新しいフィンガープリントを公開し、顧客は変更されたサービス ID を観測できたからだ。鍵単体では GitHub の顧客アカウントやリポジトリを直接開けなかったことについても高い確信がある。これは暗号上の役割と GitHub の明示的な境界に従う。厳格なクライアントや一部の SSH 設定された Actions ジョブが失敗し得たことについても高い確信がある。これは意図されたクライアント動作であり、GitHub が警告していたからだ。

秘密がどのように公開リポジトリに到達したか、どれだけの期間取得可能だったか、誰が取得したか、GitHub がどのように悪用を否定したかについての確信は低い。「そのように考える理由はない」という GitHub の声明は、誰も鍵をコピーしなかったことの証明に等しくない。公開リポジトリは迅速な複製のために設計されている。一方で、その期間のクローンやページビューだけでは悪意ある使用を証明しない。使用の証拠にはネットワークテレメトリ、開示後の古い鍵なりすまし報告、不審なエンドポイント、顧客側の接続記録が必要だろう。

より完全なプロバイダレポートは以下の 8 つの問いに答えるだろう:

  1. 秘密鍵を生成またはエクスポートしたのは何か、どの保管境界が越えられたのか?
  2. どのリポジトリ表面に露出したか、正確にどれだけの期間、どの API やキャッシュを通じてか?
  3. どの制御がそれを発見したか、失効させる権限を持つ人物にアラートが届くまでどのくらいかかったか?
  4. GitHub システムと顧客情報が侵害されなかったという結論を裏付ける証拠は何か?
  5. ホスト鍵の使用試行についてどのようなテレメトリが調査され、どのような可視性の限界が残ったか?
  6. なぜ新しい鍵は 02:30 UTC 頃から可視化されたのか、それは変更計画の範囲内だったのか?
  7. いくつのファーストパーティジョブまたはサポート対象アクションバージョンが更新を必要とし、顧客向けの回復にどのくらいかかったか?
  8. 鍵の保管、リポジトリ防止、ローテーションリハーサル、顧客通知に関してどのような恒久的な変更が行われたか?

現在のセキュリティインシデントへの対応に関する GitHub のガイダンスは、証拠の保全、決定の記録、コミュニケーション、監査データの使用を推奨している。これは今日の妥当なベンチマークだが、GitHub 自身の 2023 年の対応に対する独立した監査ではない。

現在の NIST のサイバーサプライチェーンリスクガイダンスは、サプライヤー保証、インシデント調整、緊急時計画を組織ガバナンス内に位置づけている。ここに適用すれば、保証とはプロバイダが安全であると証明する証明書ではない。プロバイダが侵害された ID を失効させ、交換品の認証方法を顧客に伝え、残余の不確実性を理解させる証拠である。

責任は実質的な制御に従う

不注意な公開者が存在したとしても、その人物は直接的な行為を制御していたが、おそらくプロダクションホスト素材を公開可能にしたシステム全体を制御していなかった。その人物を名指ししても、なぜエクスポートが可能だったのか、なぜリポジトリ制御がオブジェクトを許可したのか、なぜ検出に時間を要したのか、ローテーションが顧客にどう影響したかには答えられない。GitHub は行為者を特定しておらず、動機を帰属させる根拠もない。

GitHub のセキュリティおよびインフラリーダーシップが、最も重要なレバレッジの効くセーフガードを制御していた。ホスト鍵の生成と保管、秘密素材へのアクセス、リポジトリポリシー、検出と調査、失効のタイミング、新しい鍵のデプロイ、悪用のテレメトリ、公開フィンガープリント、ファーストパーティ Activities の更新、サポート調整、インシデント後開示の深さである。顧客は GitHub.com のホスト鍵をローテーションできず、その保管を検査できなかったため、予防的および対応的説明責任の最大の部分を負う。

GitHub はまた、中核的な封じ込め決定について賞賛に値する。運用上のコストにもかかわらず鍵を交換することは賢明な行動だった。お知らせは影響を受けるアルゴリズムを特定し、SSH と HTTPS を分離し、新しいフィンガープリントと公開鍵を提供し、手動および API ベースの更新方法を示し、02:30 の準備的提示を認め、Actions ユーザーに警告し、サポート対象タグを更新した。顧客を驚かせないように変更を隠蔽したプロバイダは、開示された秘密鍵を信頼させ続けたであろう。

組織およびエンタープライズオーナーは、GitHub がどのように自社のプロダクションチェーンに組み込まれるかを制御していた。その責任には、SSH 利用の棚卸し、厳格な検証の維持、信頼できる信頼バンドルの保持、通知へのサブスクライブ、オンコールスタッフへの承認パス提供、クライアントログの保持、代替トランスポートのテスト、重要なソースとメタデータのバックアップが含まれる。これらの責務は GitHub の公開を免罪するものではない。しかし、顧客の回復設計は GitHub が管理しないシステム上に存在することを認識するものである。

アクションおよびインテグレーションメンテナーは、埋め込まれたホスト素材、リリースチャネル、更新指示を制御していた。可変タグは迅速な修正を提供できる。固定された SHA はレビュー済みの完全性を維持できる。メンテナーは正確な修復コミットを公開し、サポートされている場合はリリースに署名するか別の方法で認証し、生きた未検証スキャンを推奨せずに信頼素材を構成可能にすべきである。

中小企業のリーダーシップは優先順位とリソースを制御していた。5 人の会社がグローバルな暗号対応チームを運用することを期待するのは不合理だ。しかし、オーナーを割り当て、テスト済みのフォールバックを 1 つ維持し、ソース制御の中断をどのくらい許容できるかを決定することは合理的だ。調達と保険者は、一般的な質問票ではなく、その結果に比例した証拠を求めるべきである。

鍵を使って GitHub になりすました攻撃者は、その攻撃に対する責任を負うであろう。レビューした公開記録ではそのような使用は確立されていない。ネットワークオペレータ、DNS プロバイダ、認証局は隣接する信頼チャネルを制御していたが、それらが失敗したか、この事象に関与したという証拠はない。仮想的な攻撃がそれらを必要とするからといって、すべての可能な参加者に責任を配分すべきではない。

警告の両方の意味を生き延びる制御セット

永続的な目標は「ホスト鍵警告を防ぐこと」ではない。警告がメンテナンスを意味する場合でも攻撃を意味する場合でも、組織が正しく対応できるようにすることだ。

プロバイダにとって:可能な限りホスト秘密鍵をエクスポート不可に保ち、プロダクション署名をリポジトリや開発者環境から分離し、すべての例外的エクスポートをログに記録する。コミット前、プッシュ時、公開後のファイルをスキャンし、汎用秘密鍵形式を含め、高確信度のプロダクション鍵アラートを直接インシデント機能にルーティングし、バイパスは稀で帰属可能かつレビュー済みにする。独立した保管ドメインに少なくとも 2 つの現代的なホスト鍵アルゴリズムを維持する。ファーストパーティクライアント、サポート対象 Actions、ドキュメント、API、サポート、顧客通知を通じて緊急ローテーションをリハーサルする。

顧客にとって:厳格なチェックを強制し、承認済みホスト鍵を構成管理を通じて配布する。SSH 経由で Git を実行するすべてのシステムを棚卸しする。プロバイダのフィンガープリントと検証 URL を制御されたランブックにキャッシュする。セキュリティ変更と運用ステータスの両方のチャネルにサブスクライブする。正確なアルゴリズムとフィンガープリントの比較を要求する。失敗した接続の証拠を保存する。スコープを限定した認証情報で HTTPS フォールバックをテストし、ミラーまたはバンドルからのリポジトリ復元をテストする。

両側にとって:ハンドオフを測定する。プロバイダの検出、封じ込め、決定、ローテーション、公開、ファーストパーティ依存関係のパッチに要する時間は内部的に可視化されるべきである。顧客の警告、検証、承認、カナリア更新、信頼デプロイ、失敗したジョブのクリアに要する時間は演習で測定されるべきである。02:30 から 05:00 UTC の間隔は、デプロイフェーズが外部にとって意味のあるタイムスタンプを必要とする理由を示している。

最終テストは意図的に不快である。ある演習では発表された交換鍵を提示し、別の演習では発表されていない偽の鍵を提示する。発表された鍵は回復目標内に検証・デプロイされるべきである。偽の鍵はブロックされ続け、傍受の疑いとしてエスカレーションされるべきである。両方とも受け入れられたらセキュリティは失敗している。両方とも無期限にブロックされたら継続性が失敗している。演習開始前にスタッフにどちらの演習かを伝えたら、組織は判断ではなくスクリプトをテストしたことになる。

アカウンタビリティの結論

GitHub の 2023 年 3 月の対応は、その中心的行為において正しかった。観測された悪用がなくとも、公開されたホスト秘密鍵はもはや信頼できる ID として存続できなかった。ローテーションはセキュリティリスクを低減した。生じた障害は付随的なノイズではなかった。それらはクライアントが、鍵が存在する目的である当の信頼決定を強制していたことの証明だったのだ。

この事象は、その証拠の範囲内にとどめるときに最も教訓的になる。それは顧客リポジトリの盗難が開示されたわけではなかった。攻撃者が GitHub に侵入した証拠ではなかった。GitHub.com の全般的な停止ではなかった。それはプロバイダ認証秘密の公開であり、その後、一部の顧客と自動化システムが不安を抱く新しい ID が本物かどうかを判断することを余儀なくされた、迅速な交換であった。

GitHub は、自社の秘密ホスト鍵が公開され得る条件と、交換シグナルの質を所有していた。顧客は、そのシグナルから開発者マシンやリリースシステムに至るラストワンマイルを所有していた。両者の間のギャップはクラウド依存そのものだった。グローバルなプロバイダは一つの新しいフィンガープリントを公開できたが、依存するすべての組織は依然としてそれを認証し、承認し、運用化しなければならなかった。

成熟したエンタープライズにとって、これは管理された信頼更新であるべきだ。中小企業にとっては、もう一つの目とテスト済み HTTPS ルートを備えた短いランブックであるべきだ。どちらにとっても答えは警告を黙らせることではない。停止したクライアントが信頼できる証拠を取得し、狭い範囲で更新し、ID がもはや重要でないかのように振る舞うことなく再開できたときにのみ、その朝は安全だったのだ。