GitHubサプライチェーン防御マップ:9つの対策を実装、ネットワークファイアウォールは依然プレビュー段階

2026年8月1日 12:47

印刷

記事提供元:Tech Times

(Github.com)

(Github.com)[写真拡大]

GitHubは、2025年後半以降にnpmとGitHub Actions向けにリリースしたサプライチェーン防御の全体マップを公開した。合計9つの対策が実装されたが、認証情報の持ち出しを防ぐネットワークファイアウォールは依然プレビュー段階にある。npmパッケージやGitHub ActionsベースのCI/CDパイプラインを運用するすべての開発チームにとって、直ちに対応すべき重要な情報である。

■実際の攻撃チェーンの全体像

2026年7月28日に公開されたプリンシパルエンジニアのGreg Ose氏とZachary Steindler氏によるブログ記事は、何が防御され、各対策が何を阻止し、どこにギャップが残っているかについて、GitHubが提供したこれまでで最も明確な全体像である。GitHubのブログ記事は攻撃パターンを非常に具体的に説明しており、どの対策がどのような役割を果たすかを評価する上で、この理解が不可欠である。

2025年9月から2026年7月にかけてnpmエコシステムを襲った攻撃(Shai-Huludワーム、Axiosの侵害、Red Hatの公式ネームスペースに対するMiasmaの波、88分間で144のAI関連パッケージにバックドアを仕掛けたMastra攻撃)は、単一の脆弱性を突いたものではなかった。これらは複数の弱点を連鎖させていた。フィッシングメールや悪意のあるプルリクエストにより、攻撃者はまずCI/CDランナーで初期のコード実行権限を得る。このランナーは、npmのパブリッシュトークン、GitHubの個人アクセストークン、OIDCトークンなど、有効期間の長い認証情報を保持している。攻撃者はランナーのメモリからこれらの認証情報を読み取る。認証情報を手に入れた攻撃者は、ランナーに公開権限があるパッケージの悪意あるバージョンを公開する。これらの悪意あるバージョンは、自動依存関係更新ツールを通じて、誰にも気づかれる前に何千もの下流プロジェクトの依存関係ツリーへと伝播していく。

これが、GitHubの記事が「包括的アプローチ(holistic approach)」という言葉を用いている理由であり、この文脈においてそれが単なる決まり文句ではない理由である。このチェーンのリンクを1つ断ち切るだけでは攻撃は止まらない。大部分を断ち切ることで、検知が機能する程度に攻撃を遅らせることができる。実装された9つの対策が試みているのはまさにそれであり、これらを合わせることで、個別の脆弱性へのパッチ適用から、攻撃パターンの各フェーズにおけるデフォルト拒否(default-deny)アーキテクチャの強制へと移行することを示している。

■初期アクセス:入り口を塞ぐ

9つの対策のうち4つは、初期アクセスフェーズ、つまり攻撃者が最初に足場を築く瞬間を標的にしている。

最も分かりやすいのは、メンテナーレベルでのアカウント乗っ取りに対する対策である。影響力の大きいnpmアカウントは、ユーザーがメールアドレスを変更したり、二要素認証のリカバリーコードを使用したりすると、72時間の読み取り専用モードに入るようになった。この遅延は、実際のフィッシングキャンペーンの手口を反映している。メンテナーの認証情報を盗んだ攻撃者は通常、本当の所有者が警告を受けて制御を取り戻す前に、アカウントの登録メールアドレスを変更する必要がある。72時間の猶予があれば、アカウントが悪意のあるパッケージのプッシュに使われる前に、正規のメンテナーが気づいて復旧させることができる。

このフェーズの残り3つの対策は、CI/CDパイプラインの脆弱性、具体的にはGitHub Security Labのセキュリティ研究者が2021年に「pwn request(乗っ取りリクエスト)」と名付け、過去2年間で最も深刻なサプライチェーンインシデントのいくつかを引き起こした pull_request_target 攻撃パターンを標的にしている。

このメカニズムは正確に理解しておく価値がある。なぜなら、Fortune 500企業の運用ワークフローにも現れており、現在も数百万のレポジトリに存在しているからだ。pull_request_target イベントは、正当な問題を解決するために2020年にGitHubによって導入された。標準の pull_request イベントはフォークされたレポジトリのコンテキストで実行されるため、ベースレポジトリのシークレット、トークン、共有キャッシュにはアクセスできない。そのため、高い権限を必要とする自動化タスク(コメントの投稿、ラベルの割り当て、カバレッジレポートなど)には役に立たない。一方、pull_request_target はベースレポジトリのコンテキストで実行され、これらのすべてのリソースにフルアクセスできる。危険なのは、開発者が信頼できないコードを実行したい場合(コントリビューターの差分テストや、実際の変更に対する認証付きカバレッジレポートの生成など)にもこれを使用し始めたことだ。このワークフローがフォークのプルリクエストのHEAD(メンテナーがレビューしていないコード)をチェックアウトし、ベースレポジトリの認証情報をスコープに入れて実行すると、プルリクエストを開くことができる攻撃者であれば誰でも、ターゲットレポジトリの完全な認証情報セットを使用して任意のコードを実行できてしまう。

7月14日のAsyncAPI攻撃は、このベクターを直接実証した。攻撃者はAsyncAPIジェネレーターのレポジトリに対して37のプルリクエストを開き、ノイズの中にエクスプロイトを偽装した。1時間以内に、設定を誤った pull_request_target ワークフローが攻撃者のコードを実行し、プロジェクトのnpmパブリッシュトークンを暴露させ、攻撃者が正当な自動化IDの下で悪意のあるコミットをプッシュすることを可能にした。これにより、合計で週に225万回以上ダウンロードされる4つのパッケージにわたって、5つのバックドア付きパッケージバージョンが公開された。

GitHubの対応は3つの部分からなる。まず、actions/checkout アクションはデフォルトで、pull_request_target および workflow_run ワークフロー内でフォークのプルリクエストコードをフェッチすることを拒否するようになった。ワークフローは allow-unsafe-pr-checkout: true を設定することでブロックされた動作を再度有効にできるが、このフラグ名はコードレビューで目立つように意図的に選ばれている。2つ目の対策として、エンタープライズ、組織、レポジトリの管理者が、ワークフローのトリガーを許可するユーザーや許可するトリガータイプに関するポリシーを設定できるようになった。3つ目は、より巧妙な権限昇格パスを塞ぐものである。信頼性の低いワークフローは、より高い権限を持つワークフローと共有されるキャッシュに書き込むことができなくなった。これは以前、限定的なコード実行権限を、リリースやパブリッシュのパイプラインが保持する認証情報へのアクセスへと変換するルートとなっていた。

チェックアウトの強制適用がカバーしていない部分であり、すべてのチームが今すぐ監査すべき点がある。それは、git やGitHub CLIを呼び出す run: ブロックを使用して信頼できない参照(ref)をプルするワークフローは、依然として完全に脆弱であるということだ。この修正は actions/checkout に限定されており、根本的なイベントトリガー自体が修正されたわけではない。

■認証情報の持ち出し:盗まれる前に無価値化する

2つの対策は、持ち出し(エグレス)フェーズ、つまりコード実行権限を得た攻撃者がランナーのメモリから有効期間の長い認証情報を読み取る瞬間を標的にしている。

構造的に最も重要なのはトラステッドパブリッシング(Trusted Publishing)であり、GitHubは現在、プロバイダーとしてCircleCIを含めるように拡張している。トラステッドパブリッシングは、CI/CDパイプラインから有効期間の長い認証情報を完全に排除する。npmのパブリッシュトークンをレポジトリのシークレット(そのレポジトリのコンテキストで実行されるすべてのワークフローが読み取れる場所)に保存する代わりに、トラステッドパブリッシングは、1回のパブリッシュ操作のみに有効で直後に期限切れとなる、スコープが限定された短命のOIDCトークンを使用する。永続的な認証情報が存在しないため、盗むものは何もない。まだトラステッドパブリッシングを使用していないチームが取るべき実践的な行動は、CI/CDにおける有効期間の長いnpmトークンの使用をやめることだ。GitHubは現在、GitHub Actions、CircleCI、およびその他のいくつかのプロバイダーからのトラステッドパブリッシングをサポートしている。

持ち出しフェーズの2つ目の対策は、まだ完了していないネットワークエグレスファイアウォールである。現在テクニカルプレビュー段階にあり、Actionsワークフローの実行からのすべてのアウトバウンドネットワークトラフィックをログに記録する。持ち出しのギャップを埋める機能、すなわちポリシーの適用と予期しないアウトバウンド接続のブロックは、「今後の課題(future work)」としてリストされている。プレビューは利用可能であり、今すぐ有効にする価値がある。ブロックモードがリリースされる前に監視モードでエグレスの許可リストを構築しておけば、適用が開始された際に、攻撃者の圧力下で緊急の監査を行うことなく、即座に有効化できるからだ。

このアーキテクチャの詳細は重要である。StepSecurityのharden-runnerを含む、GitHub Actions向けの既存のエグレス制御のほとんどは、ランナーの仮想マシン内で実行される。ランナー内でルートアクセスを取得した攻撃者は、これらを無効化できる。GitHubのネイティブファイアウォールは、ランナー仮想マシンの外側にあるネットワークインフラストラクチャレベルに配置されており、VM内のルートアクセスでは手出しができない。だからこそ、この対策は持ち出しフェーズを明確に標的にしている。これは攻撃者がコード実行だけでは回避できないレイヤーであり、それゆえに構築が最も難しく、リリースが最後になったのである。

■伝播:スピードの優位性を断つ

攻撃者が認証情報を手に入れた後、残された武器はスピードである。公開された悪意のあるパッケージは、検知されて削除される前に、できるだけ多くの下流の依存関係ツリーに到達する必要がある。9つの対策のうち3つは、この時間との戦いを標的にしている。

現在npmで一般提供されているステージドパブリッシング(Staged Publishing)は、自動化されたCI/CDによってステージングされたパッケージバージョンが一般にインストール可能になる前に、人間による二要素認証の承認を要求する。この対策は、自動化で使用される認証情報と、パッケージを一般公開できる認証情報を切り離す。盗まれたCI/CDトークンを使用しても、攻撃者は対話的な人間だけが満たすことができるライブの2FAチャレンジを完了しない限り、悪意のあるバージョンをレジストリにプッシュすることはできない。ステージドパブリッシングはオプトイン方式である。これを有効にし、パブリッシュワークフロー用に設定したチームは、認証情報の窃取からマルウェアの配布に至る攻撃チェーンを事実上断ち切ったことになる。

2026年7月8日にリリースされたnpm v12は、2つ目の伝播ベクターであるインストール時のコード実行に対処している。npmの16年間の歴史を通じて、依存関係ツリー内のあらゆるパッケージ(開発者が直接選択したことのない数階層深いパッケージを含む)は、preinstall、install、postinstall のスクリプトフックを介して、インストール時に任意のシェルコマンドを実行できた。攻撃者はこれらのフックを利用して、アプリケーションコードが実行されるのを待つことなく、開発者やCI/CDパイプラインが npm install を実行した瞬間に認証情報を持ち出していた。npm v12では、これらのスクリプトがデフォルトで無効になっている。また、gitレポジトリやリモートURLから解決される依存関係もデフォルトでブロックされる。これらは、インストールスクリプトの監視が登場した際に回避策として使用されていた2つの追加の実行パスである。

実践的な移行手順としては、今すぐnpm 11.16.0にアップグレードして、v12でブロックされるすべてのスクリプトと依存関係の警告モードプレビューを確認し、npm approve-scripts を使用してプロジェクトが本当に必要とするスクリプトの明示的な許可リストを構築し、アップグレード前にその許可リストをコミットすることだ。ほとんどの移行ガイドが省略している障害モードに注意が必要である。npm v12でブロックされたネイティブビルドは、依然として終了コード0で終了する可能性があり、ビルドが壊れていることを隠す「サイレントなグリーンのCI実行」となる場合がある。

3つ目の伝播対策は、攻撃者の経済性に最も直接的に狙いを定めたものである。Dependabotは、パッケージのリリース後3日間待機してから、バージョン更新のプルリクエストを開くようになった。理由は単純だ。悪意のあるパッケージバージョンを公開する攻撃者は、セキュリティコミュニティが気づいて削除する時間的余裕ができる前に、自動依存関係更新ツールがそれを下流プロジェクトに引き込むことに依存している。3日間の猶予があれば、監視サービス(Socket、Sonatype、StepSecurity、CISAの悪用が確認された脆弱性(KEV)カタログなど)が、悪意のあるリリースがプロジェクトのコードに到達する前にフラグを立てる時間を確保できる。セキュリティアップデートは引き続き即座に開かれるため、重要なパッチがこのクールダウンによって遅れることはない。このクールダウンは、.github/dependabot.yml の cooldown オプションを使用して、レポジトリごとに調整または無効化できる。

■インシデント対応:復旧までの時間を短縮する

最後の2つの対策は、他の対策にもかかわらず一部の攻撃は成功するという前提に立ち、侵害がすでに発生した後の被害期間を制限することに焦点を当てている。

セルフサービス型の認証情報取り消し機能により、エンタープライズ管理者やメンバーは、2026年2月にリリースされたエンタープライズ規模の認証情報管理ツールを基盤として、特定のユーザーのすべての認証情報を即座に取り消すことができるようになった。2026年3月にリリースされた拡張版の認証情報取り消しAPIは、この機能を個人アクセストークンだけでなく、GitHub OAuthおよびGitHub Appトークンにも拡張し、漏洩した認証情報がどこに現れても、どのように持ち出されたかに関係なく取り消すことを可能にした。

インシデント対応における実践的な注意点として、サプライチェーン攻撃が検知された場合、検知から認証情報の取り消しまでの1秒1秒が、攻撃者がパブリッシュ権限を保持し続ける時間となる。これらの対策により、その期間を意図的な決定事項とし、手動で認証情報ストアを探し回るのではなく、単一の操作でチームがその期間を閉じることができるようになる。

■未解決の課題

GitHubの記事は、機能だけでなく限界も明記している点で注目に値する。セキュリティ監査を実施するチームにとって、明確にしておくべき3つのギャップがある。

第一に、git やGitHub CLIを用いた run: ブロックを使用して信頼できないフォークコードをチェックアウトするワークフローは、actions/checkout の強制適用による保護を受けない。7月20日のバックポートは最も一般的なパターンを塞いだが、カテゴリ全体を塞いだわけではない。pull_request_target と明示的な git fetch または gh pr checkout を組み合わせたワークフローファイルは、依然としてpwn requestの標的となる。

第二に、ブロックモードのネットワークエグレスファイアウォールはまだリリースされていない。リリースされるまでは、GitHub Actionsランナー内でコード実行権限を得た攻撃者は、外部ドメインに認証情報を持ち出すことができる。ログ記録モードのプレビューは利用可能であり、有効にする価値がある。これによりパイプラインの通常のエグレス動作が文書化され、ブロック機能がリリースされた際の適用ポリシーの基盤となる。登録は、GitHub Actionsネイティブエグレスファイアウォールの早期アクセスレポジトリで可能である。

第三に、npm v12のインストールスクリプトのブロックは、ロード時の実行パスを塞ぐものではない。ペイロードを postinstall フックからメインモジュールのエントリポイントに移動させた悪意のあるパッケージは、アプリケーションコードがそれをインポートした瞬間に依然として実行される。レジストリの監視、プロビナンスの証明、および明示的な依存関係のレビューは、デフォルトの変更では排除できない必要なレイヤーとして残り続ける。

より大きな枠組みとして(これらの対策を「多層防御」とする当初の説明では控えめに表現されているが)、実装された9つの対策は、npmおよびGitHub Actionsエコシステム全体における、暗黙の信頼から明示的な許可リストへの真のアーキテクチャの移行を表している。HTTPSの導入、コンテナイメージの署名、証明書の失効において、同等の移行には何年もかかった。それが今、ソフトウェアパッケージのインフラストラクチャで進行中である。GitHubの記事が示しているのは、その移行の完了ではなく、攻撃者が攻撃チェーンの各フェーズ(1つを除く)で意味のある抵抗に直面するほど、移行に十分なレイヤーが備わったという時点である。

■注目ポイントQ&A

●npmでステージドパブリッシングを有効にすると、既存の自動リリースパイプラインは壊れますか?

パイプラインがCI/CDシークレットとして保存された有効期間の長いnpmパブリッシュトークンを使用している場合、ステージドパブリッシングを有効にすると、そのトークンは人間による2FA承認ステップなしではパブリッシュを完了できなくなります。有効期間の長いトークンを完全に排除し、代わりに短命のOIDCトークンを使用するトラステッドパブリッシングに移行するか、最終的なパブリッシュステップが手動承認を待つようにリリースワークフローを設定するかを決定する必要があります。ステージドパブリッシングは現在オプトイン方式であり、メンテナーが有効にしていないパッケージには何も変更をもたらしません。

●Dependabotのクールダウンとは何ですか?より迅速なアップデートが必要なパッケージで無効にすることはできますか?

Dependabotのクールダウンは、新しいパッケージリリースに対してDependabotがバージョン更新のプルリクエストを開く前に、必須の3日間の遅延を導入するものです。これはバージョン更新にのみ適用され、セキュリティ更新は引き続き即座に開かれます。チームが特定のパッケージ(たとえば、自社でリリースを管理している内部パッケージなど)でより迅速なバージョン更新を必要とする場合は、.github/dependabot.yml ファイルの cooldown オプションを使用して、より短い期間を設定するか、クールダウンを完全に無効にすることができます。GitHub Enterprise Serverのチームは、新しいデフォルトがGHES 3.23で有効になることに注意してください。

●なぜネットワークエグレスファイアウォールの実装が最後になったのですか?ブロックモードに向けて今どう準備すればよいですか?

ネットワークファイアウォールは、ランナー仮想マシンの外側であるインフラストラクチャレベルで動作します。そのため、構築がより複雑であり、防御としてより重要になります。VM内のプロセスとして実行されるツールとは異なり、ランナー内でルートアクセスを取得した攻撃者によって無効化されることはありません。監視モードは現在、早期アクセスプログラム(github.com/github-early-access/actions-native-egress-firewall)を通じて利用可能です。今日、最も重要なワークフローを監視モードに登録しておけば、ブロックモードで適用されるエグレス許可リストを構築することになります。これにより、適用が開始された際に、緊急の監査なしで有効化できます。ブロックモードの一般提供(GA)のスケジュールはGitHubから明言されていません。

●これら9つの対策は、フローティングタグではなく特定のコミットSHAに固定されているワークフローも保護しますか?

特定のコミットSHA、マイナーバージョン、またはパッチバージョンに固定されているワークフローは、2026年7月20日の actions/checkout のより安全なデフォルトの自動バックポートを受け取っていません。これらのワークフローは、新しい保護を継承するために、手動で actions/checkout@v7 またはサポートされているフローティングメジャータグ(v2からv6)に更新する必要があります。Dependabotが推奨されるアップグレードパスです。そのアップグレードが完了するまで、これらのワークフローは、フォークのチェックアウトを伴う pull_request_target または workflow_run を使用している場合、pwn request攻撃パターンの影響を受けやすいままです。

元記事: GitHub Supply Chain Defense Map: Nine Controls Shipped, Network Firewall Still In Preview

※この記事はTech Timesから提供を受けた記事を日本向けに翻訳・編集したものです。

関連キーワード

関連記事