Security

actions/checkout v7 refuses fork PR code in pull_request_target

actions/checkout v7 refuses fork PR code in pull_request_target

You trust your CI to run untrusted code. Sit with that for a second. The whole point of a pull-request-triggered workflow is that anyone, anywhere, can hand you a payload and ask your build farm to do something with it. The trick, the bit every CI platform has been quietly bad at for years, is making sure "do something with it" doesn't silently become "do anything at all, with my secrets."

GitHub announced actions/checkout v7 on its changelog. The default changed in a small, opinionated way: when a workflow triggered by pull_request_target or workflow_run tries to fetch the head of a fork PR, the action now refuses. Failing closed. Finally.

"Pwn requests," briefly

GitHub frames the change as blocking "the most common form of pwn requests." If that phrase makes you wince, you've seen the pattern: a repository wants to label, lint, or comment on a contributor's pull request, so it reaches for pull_request_target, the trigger that runs in the base repository's context, with the base repo's GITHUB_TOKEN and secrets in scope. Then, almost by reflex, the workflow checks out the contributor's branch and runs something from it. A test. A linter. A build.

That is the moment it stops being a pull request and starts being a remote shell with credentials.

Same-repository pull requests aren't the issue (you already trust your own collaborators, mostly). The plain pull_request event runs in a permissionless fork context and isn't either. The danger has always lived in the unhappy marriage of "elevated token" and "attacker-controlled checkout." That marriage is what v7 annuls.

What v7 actually refuses

According to the changelog entry, v7 fails when a checkout step inside a pull_request_target or workflow_run workflow points at a fork, patterns such as refs/pull/<n>/head, a fork repository name, or a fork commit SHA. Nothing else changes. You can still use pull_request_target to label, comment, and run base-repo code; you just can't, by accident, drag the contributor's tree into your privileged job.

A rough sketch of the shape v7 now blocks:

on: pull_request_target

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
        with:
          ref: refs/pull/${{ github.event.pull_request.number }}/head
          repository: ${{ github.event.pull_request.head.repo.full_name }}

Under the previous default that runs, with your secrets in scope, against whatever a contributor pushed. Under v7 it fails before the bytes ever land.

The opt-out, and why its name matters

There is an escape hatch, an allow-unsafe-pr-checkout input, and GitHub describes the flag as "intentionally named to be easy to spot in code review and static analysis." Read that twice. The name is the feature. A grep across an organisation's workflows for that string instantly enumerates every workflow that explicitly opted back into the dangerous pattern. Security teams who write detection rules for a living will love it; engineers who like their config to feel benign, less so.

That is the right trade. A well-named opt-out is worth more than ten lint rules.

The cutover, and what it doesn't fix

The changelog flags a backport: workflows pinned to a floating major tag will start getting the new enforcement on July 16, 2026, when GitHub backports the change to all currently supported major versions. Pinning to a resolved commit SHA buys you no escape from your own habits, but it does buy you a few weeks to read your own YAML.

What v7 does not do: stop you from curl | bash-ing a contributor's tarball inside a privileged job. It cannot. The default closes the most common door; the other doors are still your problem. Least-privilege permissions: blocks, scoped tokens, environment-protected secrets, none of that becomes optional just because the front door now has a lock.

How other CI systems draw the same line

The trust boundary GitHub just moved is universal, every CI platform has to answer the same question: what should a fork PR be allowed to do with my secrets? The answers vary in shape, not in spirit:

  • GitLab CI treats merge requests from forks as a distinct pipeline class and keeps protected variables behind explicit settings, on the assumption that fork code is untrusted by default.
  • CircleCI ships a per-project switch for whether forked PRs build at all, plus a separate switch for whether those builds inherit secrets, both off until you say otherwise.
  • Jenkins with the GitHub source plugin places fork PRs behind a build-approval gate the first time a contributor proposes a change, layered on top of org-level allowlists.
  • Drone-style schedulers simply do not pass secrets into fork builds unless a secret is explicitly marked fork-eligible.

Different shapes, same lesson: untrusted code wants your privileges, and a CI platform earns its keep by saying no on your behalf, without you having to remember which checkbox.

The kicker

For years the official answer to "is pull_request_target safe?" has been "yes, if you read the docs, never check out the PR head, and never use an action you didn't pin to a SHA." That isn't a default. That's a hazing ritual.

v7 isn't a fix for CI supply-chain security. It's the platform finally conceding that "don't shoot yourself in the foot" is its job, not yours. Take the upgrade. Grep your org for allow-unsafe-pr-checkout. And if you find it, be very sure you meant it.

Source: GitHub Changelog (github.blog)

Related
Supply-chain security

Cordyceps: when a stranger's pull request runs as a maintainer

Researchers at Novee catalogue Cordyceps, a class of CI/CD supply-chain exploit where pull requests and comments from untrusted contributors get executed with maintainer permissions. A scan of 30,000 high-impact repositories flagged 654 candidates and confirmed over 300 as fully exploitable, with named blast radius inside Microsoft, Google, Apache and Cloudflare.

July 16, 2026
Security & supply chain

GitHub Actions hands fork triggers a read-only cache token

GitHub Actions now issues read-only cache tokens to workflow events fired from outside a repository's collaborator set, applying least privilege to the default-branch cache so untrusted triggers cannot poison entries the next push reuses.

June 30, 2026
Security & supply chain

GitHub Actions hands platform teams a workflow-trigger allow list

GitHub Actions is rolling out workflow execution protections in public preview at the enterprise, organization, and repository levels, letting administrators define who and what can trigger workflows. It's the platform-owned trigger gate the CI/CD industry has been quietly working toward for years.

June 18, 2026

Turn this into your pipeline. Build it on Buddy.

Start free