前回の投稿では、 直接毒物を検出して防御する方法を見てきました Pipeline 実行(D-PPE)。また、その脆弱性を検出する方法についても説明しました。 Xygeniスキャナーまた、いくつかの保護機構も備えている。
中毒 Pipeline 処刑(PPE (People Protection Equipment)攻撃者が変更できる場合、 が生成されます。 pipeline 論理は2つの方法のいずれかで表されます。
- CI 設定ファイル ( pipeline) -> 直接個人用保護具(D-PPE)
- 参照されているファイルを変更することにより pipeline (例:内部から参照されるスクリプト pipeline 設定ファイル) -> 間接的個人保護具(I-PPE)
この記事では、間接的 PPE について詳しく見ていきます。しかし、その前に、前回の記事の補足として、GitHub が実行をどのように管理しているかを見てみましょう。 pipelineD-PPEに対する保護メカニズムとは何ですか。
GitHub は実行をどのように保護しますか pipelinePRから来ているものは何ですか?
変更されたファイルの実行に関してGitHubはどのように機能しますか? pipelines?
変更された pipelines はプッシュから来るか、 Pull Requests (PR)。 主要なベストプラクティスとして、保護されたブランチへの直接的な「プッシュ」は避け、 Pull Requests 提供されたコードを受け入れる前に、何らかの審査を強制するための仕組みとして。
Pull Requests 2つの異なる供給源から届く可能性があります。
- PRは以下から来ています フォーク
- PRは以下から来ています 支店
PRから フォーク 由来は 公共 or プライベート リポジトリ。
PPE (毒物) を扱っているため Pipeline (実行)私たちの主なポイントは、PRの「承認」ではなく、修正された実行です。 pipeline PRの承認プロセス中に発生します。PPE攻撃の中核には、「悪意のある」改変されたプログラムが意図せず実行されるという問題があります。 pipeline.
一言で言えば、ポイズンド Pipeline 実行(PPE)は、 攻撃者は pipeline ロジック.
二つあります バリアント:
- 直接個人用保護具 (D-PPED-PPEシナリオでは、 攻撃者がCI設定ファイルを改変する アクセス権のあるリポジトリ内で、リポジトリ上の保護されていないリモートブランチに直接変更をプッシュするか、ブランチまたはフォークから変更を含むプルリクエストを送信するかのいずれかの方法で変更を行います。 CI以来 pipeline 実行は変更された CI 構成ファイル内のコマンドによって定義され、攻撃者の悪意のあるコマンドは最終的にビルドノードでビルドが完了すると実行されます pipeline トリガーされます。
- 間接的な個人用保護具 (I-PPE): 特定のケースでは、D-PPE の可能性は、 SCM リポジトリ (例: pipeline (同じリポジトリ内の別の保護されたブランチからCI構成ファイルを取得するように構成されている)。 このようなシナリオでは、 pipeline 攻撃者は、 pipeline (例:内部から参照されるスクリプト pipeline 設定ファイル)
両方の場合において、 GitHub は変更された pipeline 事前の審査や承認は不要.
フォークからのプルリクエスト 公共 休息
GitHubでは、処理時の動作を設定できます。 公開リポジトリのフォークから発生したプルリクエスト.
PRがフォークから来た場合、GitHubは常に実行前に何らかの「承認」を強制します。 pipeline PRに関連するこの承認レベルは、弱い承認から厳しい承認までをトレードオフするものです。
At 組織レベル (組織>>設定>>アクション>>一般)では、いくつかの「承認」オプションから選択できます。
最も厳しいのは最後のものです(外部協力者全員からの承認が必要なぜなら、外部の協力者によるフォークからプルリクエストが送られてきた場合、GitHub は常に承認を必要とするからです。
しかし、この厳密なケースでも、 読み取り権限と書き込み権限を持つ共同作業者間の違い.
- PRが read ユーザー、 の実行 pipeline 停止しました 変更が承認されるまで。承認が問題なければ、変更された pipeline 実行されます。
- PRが 書きます ユーザー、 承認は不要で、修正された pipeline 常に実行されます!!
結論として、公開リポジトリのフォークから作成されたプルリクエストは、PPE(個人保護環境)に対する保護が不十分です。外部(読み取り)ユーザーに対する保護はありますが、内部(書き込み)ユーザーに対する保護はありません。
どうですか プライベートリポジトリのフォークから発生したプルリクエスト?
フォークからのプルリクエスト プライベート 休息
このシナリオでは、GitHubはいくつかの便利な設定項目を提供します。
上記の設定は、以下のいずれかの場所で構成できます。 オルガン またはで レポ レベル。
どのオプションもチェックされていませんGitHubは 承認を求める (NAIST) と 変更されたコードは実行されません pipelineこれが最も安全な構成です!!
その 最も危険な構成 時であります フォークからワークフローを実行する pull request」がチェックされていますこの場合、読み取りユーザーと書き込みユーザーの両方で同様に、GitHub は変更されたファイルを自動的に実行します。 pipeline!! そしてこの状況はさらに もっと悪い もし "フォークからワークフローに書き込みトークンを送信する pull requests"と"フォークからワークフローにシークレットと変数を送信する pull requests「」がチェックされています。明確な理由がない限り、これを行わないでください!!
「フォークの承認が必要 pull request ワークフロー」がチェックされると、上記の状況は多少改善されます。GitHub は承認を求め、変更されたファイルを実行しなくなります。 pipeline 読み取りユーザーに対しては実行されますが、書き込みユーザーに対しても実行されます。
フォークが見えた、 支店から送られてくるPR?
PRから 支店
このシナリオを保護するには、 ブランチ保護ルール.
リポジトリレベルでは、任意のブランチに対してブランチ保護ルールを作成できます。これらのルールはいくつかの機能を追加します。 保護された分岐の変更に対する制約.
ルールを設定すると「必要 pull request 合併前に"と"承認が必要" 修正された pipeline PR作成時に自動的に実行されます「承認」はマージ操作にのみ適用されます。
間接的な毒殺はどうでしょうか Pipeline 実行
前述のように、D-PPEは、 プルリクエスト対象が、それ I-PPEには適用されません.
pull_request_target を使用する場合、デフォルトのチェックアウトはベースコードになります。ただし、コントリビュートされたコード (PR コード) に対していくつかのチェックを検証したい場合は、PR コードを明示的にチェックアウトする必要があります。したがって、PR コードが、によって呼び出されるシェル スクリプトを変更している場合は、 pipeline「基地」(安全地帯) pipeline 「変更された」シェルスクリプトが呼び出されます → 間接的なPPE!!
これに対する解決策はもう少し複雑です(pull_request_targetのような魔法の解決策はありません)。
現場の声を力強いメッセージへ。 pipeline pull_request_targetを使用しているため、D-PPEに対しては安全になりました。しかし、I-PPEに対しては依然として脆弱です。
今回のテスト例では、基本的にビルドを行うためにプルリクエストのコードをチェックアウトする必要がありますが、テストはビルドによって生成された成果物に対して実行されます。
だから.. 両方のコードベースをチェックしてみてはどうですか?
- PRコードを確認してください。なぜなら、それは私たちが構築およびテストしたい貢献コードだからです。
- チェックアウトベースコードを実行して、元のバージョンを実行します。 pipeline ビルド/テストスクリプト
これは、 それらのコードベースを別のフォルダにチェックアウトするベースコードはルートフォルダにチェックアウトされ、プルリクエストは別のフォルダにチェックアウトされる場合があります。この場合、ルートフォルダからビルドスクリプトとテストスクリプトを実行し、新しいフォルダに配置されたコードに対してテストを実行します。
これはもちろん簡単な解決策です!! しかし、学習目的で、非常に興味深い別の方法を紹介したいと思います(…)
GitHub ワークフロー実行 トリガーイベント
ほかに プルリクエスト対象GitHubは別のトリガーイベントを提供します。 ワークフロー実行このイベントでは 実行 pipeline 別のものに条件付けられる pipelineの処刑.
ワークフロー実行 (NAIST) と プルリクエスト対象 トリガーは、ある点で似ています。どちらも特権モードで実行され、 PRの変更にもかかわらず、ベース pipeline 実行されます!!
現在の状況を見てみましょう pipeline:
ビルドセクションはD-PPEに対して安全ですが、テストセクションはI-PPEに対して脆弱です。
その pipeline それ自体はD-PPEに対して安全です。 プルリクエスト対象 トリガーが作動する。しかし、テスト手順は外部シェルスクリプトを呼び出すため、依然としてI-PPEの脆弱性を抱えている。
I-PPEを避ける
上記の目的は pipeline 貢献されたコードを構築およびテストし、PPEに対して安全であることを保証することです。
だから.. 分割しないのはなぜですか pipeline 2つに? 1つは構築用、もう1つはテスト用..
- 1st pipeline (CIの構築) NS PRコードを確認してください(ビルドするには)。ビルドを作成し、成果物を生成します。
- 2nd pipeline (テストCI) NS ベースコードをチェックアウトする(シェルスクリプトの変更を避けるため) そして、成果物に対して元のスクリプトを実行します。
- テストCIを同期するには pipeline ビルドCIの後に実行する pipeline、私たちは使用します ワークフロー実行 引き金。
このようにして:
- pipeline CIの構築 is 安全な 両方へ D-PPE (のため プルリクエスト対象)と I-PPE (シェルスクリプトが実行されなくなったため)。
- pipeline テストCI も 安全な 両方へ D-PPE (のため ワークフロー実行)と I-PPE (ベースコードをチェックアウトして元のシェルスクリプトを取得するため)
両方のコードを見てみましょう pipelineこれらの変更によると…
1 pipeline (CIの構築):
2 pipeline (テストCI):
わあ…素晴らしい解決策ですね!!でも…私たちは安全なのでしょうか?残念ながらそうではないと思います😭
確かに、新たな脆弱性を発見してしまいました!どの脆弱性かって?それは次回の投稿でご紹介します🙂…お楽しみに!
PS: ごめんなさい、黙っていられません🤐 ..聞いたことありますか? 人工物中毒 ? 😂




