On June 18, 2026, GitHub updated actions/checkout to prevent fetching fork pull request code when triggered by pull_request_target or workflow_run events. This change addresses an attack pattern where contributors submit malicious pull requests to execute arbitrary code with access to your repository's secrets. GitHub backported this protection to all supported major versions on July 16, 2026.
Understanding the Update
The pull_request_target trigger runs workflow code from your base branch but operates in the context of the pull request, creating a risk: your trusted workflow code runs with write permissions and access to secrets while processing untrusted input from an external contributor.
Attackers exploited this by submitting pull requests with payloads in file paths, branch names, or commit messages. When workflows checked out the fork's code or processed these inputs without sanitization, the malicious payload executed with your repository's privileges.
GitHub's update blocks this exploitation path: actions/checkout now refuses to fetch fork code when running in pull_request_target or workflow_run contexts unless you explicitly set persist-credentials: true and acknowledge the risk.
Timeline of Changes
Pre-June 2026: Workflows using pull_request_target with actions/checkout could inadvertently execute code from untrusted forks. Security researchers documented multiple exploitation techniques, but no automated prevention existed.
June 18, 2026: GitHub releases actions/checkout v7, blocking fork code fetches in high-risk workflow contexts by default.
July 16, 2026: Backport deployed to all supported major versions, affecting workflows across GitHub Enterprise Server and GitHub.com.
Post-deployment: Teams with legitimate use cases for fork code access must explicitly opt in, forcing a security decision at configuration time.
Identifying Control Failures
Three control gaps enabled this attack pattern:
Input validation failure: Workflows processed contributor-controlled data without sanitization, treating these strings as trusted input when they originated from an untrusted source.
Least privilege violation: pull_request_target grants write permissions and secret access by default. Many workflows needed only read access but received full write tokens due to incorrect trigger selection.
Insufficient code review of workflow definitions: Teams often reviewed application code carefully but overlooked .github/workflows/*.yml files as security-sensitive code. Workflow changes merged without security review, especially when they "just added a CI check."
Compliance Standards and Requirements
PCI DSS v4.0.1 Requirement 6.3.2 mandates that custom software be reviewed prior to release to identify and correct security vulnerabilities. Your workflow definitions are custom software and require the same security review as other code changes.
OWASP ASVS v4.0.3 Section 5.1.3 requires applications to verify the origin of data and apply appropriate validation. Treat workflow inputs like user-submitted form data.
NIST 800-53 Rev 5 Control AC-6 (Least Privilege) requires users and processes to operate with the minimum privileges necessary. Use pull_request (read-only) instead of pull_request_target (write access) when possible.
SOC 2 Type II CC6.1 requires access controls to protect against unauthorized access. A workflow that exposes sensitive tokens to untrusted code fails this control.
Action Items for Your Team
Audit every workflow using pull_request_target. Run this command in your repository root:
grep -r "pull_request_target" .github/workflows/
For each match, evaluate if the workflow needs write access, processes data from github.event.pull_request.*, or checks out fork code. If yes, you have a potential vulnerability.
Replace pull_request_target with pull_request where possible. Most test and lint workflows don't need write access. The pull_request trigger runs the contributor's workflow in an isolated environment with a read-only token.
If you must use pull_request_target, never check out fork code. Remove any actions/checkout step that includes ref: ${{ github.event.pull_request.head.sha }}. Run checks against the base branch only or use a separate isolated workflow for untrusted code.
Sanitize all external input before use. Validate contributor-controlled data explicitly:
- name: Validate branch name
run: |
if [[ ! "${{ github.event.pull_request.head.ref }}" =~ ^[a-zA-Z0-9/_-]+$ ]]; then
echo "Invalid branch name"
exit 1
fi
Add workflow changes to your security review process. Update your pull request template to flag .github/workflows/ changes for mandatory security review. Train reviewers to assess triggers, permissions, and external input processing.
Test your workflows with malicious input. Create a test repository and submit pull requests with payloads in branch names, commit messages, and file paths. Verify your workflows fail safely.
Document your decision for every pull_request_target use. Add a comment in the workflow file explaining why you need write access and how you've mitigated the risk.
The GitHub update removes one exploitation path, but the underlying problem remains: CI/CD workflows are privileged code that processes untrusted input. Treat them accordingly.



