Introduction

pull_request_target is powerful because it runs in the security context of the base repository, not the fork. That is exactly why it becomes dangerous when a workflow checks out and executes code from the pull request head. A malicious contributor can turn that behavior into privileged code execution, secret exposure, or write access abuse unless the workflow is designed to keep trusted and untrusted code paths separate.

Symptoms

  • GitHub warns that a pull_request_target workflow may be vulnerable
  • The workflow checks out PR head code and then runs scripts with repository permissions
  • Maintainers want to comment on or label fork PRs, but the workflow also executes contributor code
  • Security review flags the workflow as unsafe even though it appears to work

Common Causes

  • pull_request_target is used when pull_request would have been sufficient
  • The workflow checks out github.event.pull_request.head.sha and executes repository scripts
  • Secrets or write-scoped tokens are available in the same job that executes fork-controlled code
  • The workflow mixes safe PR metadata actions with unsafe build or test steps

Step-by-Step Fix

  1. 1.**Use pull_request when you do not need privileged repository context**
  2. 2.If the workflow only needs to test untrusted PR code, prefer the safer event.
yaml
on:
  pull_request:
  1. 1.**Keep pull_request_target jobs limited to trusted operations**
  2. 2.Use it for labeling, commenting, or other base-repo controlled actions, not for executing fork code with elevated permissions.
  3. 3.Never execute PR head code in the same privileged job
  4. 4.If you must inspect PR code, do it in a separate low-privilege workflow path with no secrets or write tokens.
  5. 5.Review third-party actions and token permissions
  6. 6.Even a well-designed workflow becomes risky if it grants unnecessary write permissions or uses unpinned external actions carelessly.

Prevention

  • Default to pull_request for untrusted code execution
  • Use pull_request_target only for narrowly scoped trusted automation
  • Separate privileged metadata actions from build and test execution
  • Audit workflow permissions and checkout behavior whenever fork support changes