# pull_request_target を安全に使用する

pull_request_target eventのセキュリティ リスクについて説明します。

このガイドは、ワークフローで `pull_request_target` イベントを使用する必要があるかどうかを評価し、関連するセキュリティ リスクを理解するのに役立ちます。 また、既定でこれらのリスクを軽減するために、GitHub v7 以降に適用される保護`actions/checkout`と、必要に応じてその保護をオプトアウトするタイミングについても説明します。

これらのワークフローのいずれかからプル リクエストのコードをチェックアウトする前、または `pull_request_target` で [](/ja/actions/reference/workflows-and-actions/events-that-trigger-workflows#pull_request_target) 入力を設定する前に、`allow-unsafe-pr-checkout` を読んでください。

## pull\_request\_targetイベントのリスク

`pull_request_target`によってトリガーされるワークフローは、昇格された信頼で実行されます。ジョブはベース リポジトリの`GITHUB_TOKEN`を受け取り、リポジトリと組織のシークレットへのアクセスを受け取ります。 これは、コラボレーターのみがトリガーできる `push` などのイベントに与えられるのと同じ信頼であり、ラベル付け、トリアージ、認証済み状態チェックの投稿など、フォークからのプル要求に応答する自動化に `pull_request_target` 役立ちます。

これが既定で安全である理由と、その安全性が一般的にどのように壊れているかを理解するには、`pull_request_target`に対する`pull_request`を確認します。

(`pull_request`および`pull_request_review`と共に) `pull_request_review_comment` イベントは通常とは異なっており、**pull request のマージ コミット**からワークフロー ファイルが実行されます。 フォークから開かれたプル要求の場合、そのコミットは、ベース リポジトリへの書き込みアクセス権を持たないユーザーによって制御されます。 信頼されていないワークフロー コードを安全に実行するために、 GitHub はこれらのイベントを読み取り専用の `GITHUB_TOKEN`に制限し、他のシークレットへのアクセスを保留し、フォーク承認ポリシーを適用してコンピューティングの不正使用を防ぎます。 詳細については、「[ワークフローをトリガーするイベント](/ja/actions/reference/workflows-and-actions/events-that-trigger-workflows#pull_request)」を参照してください。 既定では、`actions/checkout` ワークフロー内の`pull_request`は pull request のマージ コミットもチェックアウトするため、コードはチェックアウトされ、実行されるワークフローは一貫しています。

`pull_request_target` では、重要ではあるものの微妙な変更が 1 つあります。つまり、ワークフローと、`actions/checkout` を指定しない後続の `ref` 呼び出しは、プル リクエストからではなく、**ベース リポジトリの既定のブランチ**から取得されます。 既定のブランチの信頼されたコードのみが実行されるため、シークレットと読み取り/書き込みトークンを許可しても安全です。 既定では、フォークのコードは実行されません。

ワークフロー作成者がこの既定値をオーバーライドしてフォークのコードを実行すると、リスクが発生します。 開発者は、CI を介してフォークのプル要求を実行`pull_request_target`、シークレットにアクセスする (プライベート レジストリを必要とするテストを実行するなど) ため、\_\_ を頻繁に選択します。 これを行うには、既定のブランチではなく pull request ヘッドで `actions/checkout` をポイントします。これは安全ではありません。

```yaml
# INSECURE. Provided as an example only.
on:
  pull_request_target:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
        with:
          ref: ${{ github.event.pull_request.head.sha }}
      - name: Test
        run: make test
```

チェックアウト手順だけでは、信頼されていないコードは実行されません。 ワークフロー ファイル自体は、引き続き既定のブランチから取得されます。 この脆弱性は、現在の作業ディレクトリにチェックアウトされたコードを実行する *次* の手順で完了します。 ここでは、`make test` はプルリクエストのヘッドから取得した `Makefile` を実行します。 攻撃者は、 `Makefile` (またはビルド スクリプト、テスト コマンド、依存関係、または構成ファイル) に悪意のあるコマンドが含まれているフォークからのプル要求のみを開く必要があります。 これらのコマンドは、ベース リポジトリのシークレットとトークンを使用して実行されます。

このパターンは "pwn 要求" と呼ばれ、複数のサプライ チェーン侵害の根本原因となっています。 詳細については、[](https://securitylab.github.com/resources/github-actions-preventing-pwn-requests/)からの GitHub Security Labを参照してください。 脆弱な一般的な図形は次のとおりです。

* `actions/checkout` (`ref: ${{ github.event.pull_request.head.sha }}`、`ref: refs/pull/${{ github.event.pull_request.number }}/merge`) でプルリクエストのヘッドコミットまたはマージコミットをチェックアウトしてから、その結果をビルド、テスト、またはその他の処理を実行すること。
* フォーク (`repository:`) に`repository: ${{ github.event.pull_request.head.repo.full_name }}`を設定して、フォークの分岐を直接プルします。
* `actions/checkout` の外部でプルリクエストのコードを取得し（たとえば、`git fetch`、`gh pr checkout` を使用するか、フォークの `pull_request` 実行で生成されたアーティファクトをダウンロードして）、その後実行します。

Pwn 要求も `pull_request_target`に固有ではありません。 シークレットを使用して実行されるイベントは、信頼されていないコードをチェックアウトまたはダウンロードして実行する場合に pwn 要求を発生させることができます。 たとえば、フォークのプル要求コードをフェッチして実行する `issue_comment` または `workflow_run` ワークフローは、同様に脆弱です。
`workflow_run` ワークフローは、他のワークフローによってアップロードされた成果物を信頼されていないデータとして扱う必要があります。その内容はフォークから取得される可能性があるためです。

## pull\_request\_targetを使用するかどうかを決定する

一部のワークフローでは、より高い信頼レベルでフォークされた pull request のコードをチェックアウトする必要があり、そのためにそもそも `pull_request_target` が作成されました。 たとえば、プライベート成果物レジストリを必要とするカバレッジ レポートを生成したり、pull request から導入された変更に対して認証済みチェックを生成して実行したりします。
`pull_request_target`を使用する前に、または `allow-unsafe-pr-checkout` で `actions/checkout` フラグを選択する前に、以下の質問を検討してください。

* **代わりに `pull_request` を使用できますか?**
  `pull_request` は、 `pull_request_target` と同じイベントに対してトリガーされ、 `pull_request` マージ ブランチからワークフロー コードを実行します。 これは、上記で説明した保護機能により、フォークから送られたプルリクエストに対しても安全に実行されます。 追加のシークレット アクセスが必要ない場合は、 `pull_request`を使用します。 より複雑なワークフローを再構築して、プル要求コードの潜在的に危険な処理とシークレットへのアクセスを分離できます。 詳細については、[](https://securitylab.github.com/resources/github-actions-preventing-pwn-requests/#preventing-pwn-requests)からの GitHub Security Labを参照してください。

* **チェックアウトされたコードは実行されていますか?** これは、pwn 要求の脆弱性が発生する欠陥です。 最も一般的な導入方法は、`actions/checkout` にあるように、プル要求をチェックアウトして作業ディレクトリに取り込み、実行することです。
  `path`入力が設定されていない限り、`actions/checkout`はコードを `$GITHUB_WORKSPACE` ディレクトリに書き込みます。これは通常、後続のコマンドが実行される作業ディレクトリです。 実行は、独自の手順に限定されるものではなく、 `npm install` や `npm run build`などのコマンドのビルドとテスト、およびコードによってもたらされる構成ファイルと依存関係によって、攻撃者が制御するコードをすべて実行できます。 実行には明確なビルド ステップは必要ありません。
  **チェックアウトされたコードがデータとしてのみ検査され、 `pull_request_target` イベントを使用する前に実行されないようにする必要があります**。

## pull\_request\_target ワークフローの強化

`pull_request_target`が必要であることを確認した場合は、これらのコントロールを適用して、この危険度の高いイベントの影響を制限します。 これらは、ワークフローがプル要求コードをチェックアウトするかどうかに適用されます。

* **シークレットを制限します。**
  `GITHUB_TOKEN`に設定されたアクセス許可に最小限の特権があること、およびワークフローに必要なリポジトリと組織のシークレットのみが使用されていることを確認します。 詳細については、「[ワークフローでの認証に GITHUB\_TOKEN を使用する](/ja/actions/tutorials/authenticate-with-github_token#modifying-the-permissions-for-the-github_token)」を参照してください。

* **キャッシュへの影響について理解します。** キャッシュポイズニングのリスクを軽減するために、 `pull_request_target` によってトリガーされるワークフローには、既定のブランチのスコープ内のキャッシュへの読み取り専用アクセス権があります。 これらのワークフローは、既存のキャッシュ エントリを復元できますが、作成または上書きできないため、共有キャッシュを介した他の関連のないワークフローの実行に影響を与えることはできません。 このようなワークフローがキャッシュを保存しようとすると、保存は失敗しますが、ステップとジョブは続行され、エラーはワークフロー ログに警告として報告されます。 ワークフローにキャッシュを設定する必要がある場合は、 `push`などの信頼されたトリガーで実行されるワークフローからキャッシュを保存します。 詳細については、「[依存関係キャッシュのリファレンス](/ja/actions/reference/workflows-and-actions/dependency-caching#cache-access-for-low-trust-workflow-triggers)」を参照してください。

* **基になるコンピューティングが分離され、一時的であることを確認します。** セルフホステッド ランナーを使用する場合は、ランナー環境が内部リソースから適切に制限されており、 GitHub Actions 実行間で再利用されていないことを確認する必要があります。 詳細については、「[セキュリティで保護された使用に関するリファレンス](/ja/actions/reference/security/secure-use#hardening-for-self-hosted-runners)」を参照してください。

* **GitHub Actionsセキュリティのベスト プラクティスを適用します。** pwn 要求の特定のリスクに加えて、コマンドインジェクションなどの他の一般的な脆弱性が存在し、この特権イベントで実行されるコードに影響を与える可能性があります。 詳細については、「[](https://securitylab.github.com/resources/github-actions-untrusted-input/)」を参照してください。 一般的なGitHub Actionsの脆弱性を特定して予防的に保護するには、CodeQLのGitHub Actionsを有効にします。 詳細については、「[コード スキャンの既定セットアップの構成](/ja/code-security/how-tos/find-and-fix-code-vulnerabilities/configure-code-scanning/configure-code-scanning)」を参照してください。

## 組み込みの保護機能を無効にする

上記の質問に取り組み、ワークフローに `pull_request_target` が必要であり、安全に使用されていることを確認した場合は、 `actions/checkout` 保護をオプトアウトできます。
`allow-unsafe-pr-checkout: true` を `actions/checkout` の入力として設定することで、フォークからのプル要求のヘッドリファレンスをチェックアウトできるようになります。 チェックアウトされたコードが実行されていないことを確認した後でのみ、これを行います。 入力は意図的にコード レビューと静的分析で見つけやすいように名前が付けられています。

この保護機能は、フォークのプル要求の参照にのみ適用されます。 関連のないサードパーティリポジトリ、 `git fetch` または `gh pr checkout`を使用したコードのフェッチ、ダウンロードした成果物の実行など、他の信頼されていないコードのチェックアウトは、 `actions/checkout` チェックの対象になりません。

## pull\_request\_targetの使用を制限する

リポジトリに `pull_request_target`の正当な用途がない場合、イベントを制限すると、個々のワークフローの書き込み方法に関係なくリスクが排除されます。 管理者は、ワークフロー実行保護を使用して、ワークフローをトリガーできるイベントとアクターを制御できます。 詳細については、リポジトリ ([ワークフロー実行の保護](/ja/repositories/managing-your-repositorys-settings-and-features/actions-policies/workflow-execution-protections)))[](/ja/organizations/managing-organization-settings/actions-policies/workflow-execution-protections)のワークフロー実行保護に関するドキュメントを参照してください。