Skip to content
Latchkey

poisoned pipeline executionとは何か? secretを持って信頼できないコードを実行する

poisoned pipeline execution (PPE) とは、誰かがCIパイプラインに自分の制御するコードを、パイプラインが持つすべてのsecretと権限で実行させる攻撃です。

PPEは最も鋭いCI攻撃の1つです。パイプライン自身の信頼を悪用するからです。攻撃者はあなたのサーバーに侵入するのではなく、あなたのパイプラインに彼らのコードを代わりに実行させます。それはあなたのsecret、deploy key、署名IDを伴います。最も一般的な入口は、信頼できないコントリビューターからのpull requestです。

PPEの仕組み

攻撃者は、パイプラインファイル、build script、あるいはパイプラインが読み込むconfigを編集することでパイプラインが実行する内容に影響を与え、その変更がsecretを付けて実行されるように仕向けます。パイプラインは自身の設定を信頼し、敵対的なコードを従順に実行します。

直接的、間接的、パブリックなPPE

  • 直接的: 攻撃者がパイプライン定義そのものを編集する。
  • 間接的: パイプラインが実行するもの (script、Makefile) を編集する。
  • パブリック: fork pull requestが特権的なworkflowをトリガーする。

fork pull requestの罠

古典的なパブリックPPE: あるworkflowがsecretへのアクセスを持ってpull requestで実行されます。外部のコントリビューターが、buildを変更してsecretを自分のサーバーにダンプするPRを開きます。パイプラインは、誰かがレビューする前にPRのコードを実行します。pull_request_targetのようなトリガーはここで悪名高いです。

PPEの防止

信頼できないコードをsecretと共に実行しないでください。fork PRのworkflowからsecretを差し控え、外部からの貢献に対する特権的な実行の前に承認を要求し、パイプラインとbuildのファイルをレビューが必要な保護されたコードとして扱い、actionを信頼できるバージョンにpinしてください。

着地したPPEの封じ込め

多層防御は、防止が失敗しうると想定します。least privilegeのtoken、エフェメラルな認証情報、egressフィルタリング、分離されたランナーによって、成功したPPEでさえ見つけられるsecretはわずかで、それをどこにも送れず、存続もできません。爆発半径は1つの使い捨てjobの中に留まります。

重要なポイント

  • poisoned pipeline executionは、攻撃者のコードをパイプラインの権限で実行します。
  • secretを取得するfork pull requestが、古典的なパブリックPPEのベクターです。
  • 信頼できない実行からsecretを差し控え、least privilegeと分離で封じ込めます。

関連ガイド