何が起きたか・対象

Branch Deploy Actionは、管理者のコメントを契機にPRをデプロイするGitHub Actions用の機能です。承認コメントの後でPRの最新SHAを取得し、コミット作者時刻がコメントより前なら承認対象として扱う検査に抜け道がありました。識別子はGHSL-2025-038です。

攻撃者はGitコミットの作者時刻を自分で設定できます。承認後、ActionがPRの最新SHAを取得する前に、古い作者時刻を付けた別のコミットをPRへpushすると、Actionは新しいSHAでも時刻検査を通す場合がありました。ActionがそのSHAを出力すると、後続のcheckoutは対応するコードをジョブの作業ディレクトリへ取得します。デプロイ手順が取得したスクリプトを起動する構成なら、管理者が見ていないコードが本家の実行環境で動きます。

フォークを許可し、push後の承認取消や必須チェックなどが止めない構成が条件です。動いたコードがジョブへ渡された秘密を読み外部へ送れるなら漏えいも起こり得ますが、研究報告を実際のトークン窃取の観測とは扱いません。

報告・修正・公開の時系列

2025-01-30に報告され、03-14にdeployment_confirmationを含むv10.4.0が公開されました。研究公開は04-22、検証対象はv10です。新機能が提供されたことと、利用する設定で保護が有効なことは別に確認します。

正常ならどう動くはずだったか

管理者が確認したコミットのSHAを承認対象として記録し、後続ジョブはそのSHAで取得した内容を実行する必要があります。SHAはそのコミットの内容を特定するため、後からブランチへ別コミットをpushしても、記録したSHAの内容は別物へ変わりません。

ただし承認後にPRの先頭を問い合わせ、その時点の最新SHAを採用すると、SHAで取得するコードであっても承認した内容とは違う可能性があります。承認時のIDと実行時のIDが一致することを確認し、作者が変更できる時刻だけを一致の根拠にしません。

技術的な原因

Actionは承認コメントの後でPRのSHAを取得し、そのコミットの作者時刻がコメントの時刻より前かを検査していました。攻撃者はGitコミットの作者時刻を設定できるため、承認後に追加したコードでも、古い時刻を記録できます。内容の識別子ではなく投稿者が決める時刻を根拠に、承認対象と実行対象の一致を判定していたことが不備です。

攻撃が成立する条件と流れ

管理者がPRへ承認コメントを送った後、ActionがPRの最新SHAを取得する前に、攻撃者が作者時刻を古くした別コミットをPRへpushします。Actionが最新のSHAを選び、時刻検査を通して出力すると、後続のcheckoutとデプロイが差し替えたコードを取得・実行します。フォークを許可し、push後の承認取消や必須チェックなどの追加保護が働かないことが条件です。

確認された事実と、想定される影響

未承認コードの実行は、承認を受けた元のコードではなく、後で差し替えたコードがデプロイ用ジョブで動くことを意味します。説明用に、利用側のworkflowがトークンを環境変数に設定して取得済みスクリプトを起動する構成を考えます。差し替えたスクリプトがその変数を読み、攻撃者のサーバーへHTTP送信できると、攻撃者はトークンを入手します。

ジョブに書き込みや公開の権限がある構成なら、コードがそのトークンを使ってリポジトリのファイルを変更したり、不正な配布物をアップロードしたりするおそれがあります。何を変更できるかは、利用側がジョブへ渡す資格情報と実際のデプロイ手順で決まります。資料は全利用者の侵害や、実際の秘密窃取を確認した報告ではありません。

実際の修正・対応方針

v10.4.0で追加されたdeployment_confirmationと、ブランチ保護や必須チェックの設定を確認します。版を上げただけで全構成が保護されるとは扱いません。一般的な根本対策は、承認した不変のコミットのコードを実行するよう固定することです。 必須チェックは、対象コミットのテストなどが成功していることを実行条件にする仕組みです。push時に承認を取り消す設定なら、差し替え後に改めて承認が必要になります。deployment_confirmationの細かな確認手順と有効化条件は本記事では未確認のため、名前だけを根拠に保護済みとは判断しません。

利用者・運用者が確認すること

利用版、フォークの許可、確認機能、push後の承認の扱い、必須チェックを確認します。承認時のSHAと実際に取得・実行したSHAを照合できる記録も残すと、取り違えを調べられます。

開発者への教訓(教材としての考察)

コミットの作者時刻が古くても、管理者がその内容を確認した証明にはなりません。承認時に確認したコミットIDと、実行するコードのコミットIDを照合する必要があります。SHAで取得していても、そのSHAを承認後のPRから選び直す実装なら、承認対象が変わる余地が残ります。

出典・確認範囲

  1. [1] TOCTOU in GitHub IssueOps Branch Deploy ActionGitHub Security Lab / 確認日 2026-10-29
未確認事項・限界

実悪用や個別組織の侵害は資料で確認できません。