For weeks, I have been repeating the same warning in my audits and my guides:
a workflow running on pull_request_target that checks out code from a fork is
an open door to the theft of your secrets. This attack has a name, the pwn
request, and it has caused very real damage. The good news of June 2026:
GitHub finally ships a default guardrail in actions/checkout@v7. Here is
what it changes in practice, the exception you must not leave lying around,
and why almost every repository will be affected by mid-July.
What is a pwn request?
A pwn request abuses pull_request_target, the trigger that runs the workflow
definition of the target repository (yours), with access to secrets, even
for a PR coming from a fork. The trap: if a step then checks out the PR
code (ref: github.event.pull_request.head.sha) and executes it (an
npm install, a build script), it is the attacker's code that runs with
your credentials. For the details and the safe patterns, I have a dedicated
guide: Sécuriser pull_request_target.
What does checkout v7 change?
Checkout v7 inverts the default: the dangerous checkout now fails instead of
silently succeeding. Until now, nothing technically prevented it; the
responsibility rested entirely on the maintainer. With actions/checkout@v7,
when a pull_request_target workflow (or certain workflow_run workflows) tries
to fetch the ref of a fork (the branch or the SHA of the PR), checkout
refuses the operation. The dangerous pattern breaks instead of silently
pulling untrusted code into a privileged runner.
This is a real change of philosophy: the guardrail moves from "good luck, be careful" to a deny by default. The right default value, at last.
allow-unsafe-pr-checkout: which exception should you watch?
The allow-unsafe-pr-checkout input explicitly re-enables the old behavior,
and that makes it the flag to hunt for. Some legitimate workflows need the PR
code (a linter that comments on the PR, for example). For those cases, checkout
v7 adds this opt-in escape hatch.
My advice: grep your repositories for allow-unsafe-pr-checkout and demand a
written justification for every occurrence.
Why does the July 16 backport affect almost every repository?
The backport matters because the protection is not reserved for those who
upgrade to v7. This is the point many people will miss. According to the
analysis by Socket,
the protection is backported on July 16, 2026 to all supported major
versions. Since the overwhelming majority of workflows pin checkout to a
floating tag (actions/checkout@v4, @v3), they will automatically
inherit the new behavior on that date.
Concrete consequence: if one of your pipelines relies today on a fork
checkout under pull_request_target (knowingly or not), it may break on July
16. Better to audit it now than to discover it in production.
This backport illustrates a pinning trade-off: a floating tag (@v4)
receives this change for free (here, a pleasant surprise), but it also
exposes you to unwanted changes; SHA pinning
makes you master of the schedule, at the cost of having to adopt checkout
v7 yourself to get this protection. Both positions are defensible, as long as
you choose knowingly.
What does checkout v7 not fix?
A guardrail is not a waiver of rigor. This change reduces one class of attack, it does not secure your workflows for you:
- Template injection (
${{ github.event.issue.title }}inside arun:) remains entirely possible. - Overly broad permissions on the
GITHUB_TOKENremain a problem if you do not explicitly reduce them. - The two-workflow pattern (an unprivileged
pull_requestworkflow that builds, a privilegedworkflow_runworkflow that publishes) remains the right architecture to handle fork PRs cleanly.
All of this is covered in the guide Attaques supply chain sur GitHub Actions.
Should you keep using pull_request_target?
My default answer is no: I advise against pull_request_target. Let me be
clear about my position. The checkout v7 guardrail is good news, but this trigger
remains the most dangerous one in GitHub Actions, and most needs can be
covered differently:
- to test or build a fork PR:
pull_request(without secrets) is enough; - for a privileged step (deploying a preview, publishing a comment): the
two-workflow pattern connected by
workflow_run, or an API-only action without any checkout of the fork code.
I reserve it for the rare cases that never execute the fork's code (labeling, commenting through the API), and even then, only after really weighing the need. A trigger you do not use is a trigger you do not have to secure.
What would I do right now?
- Locate the workflows at risk:
grep -r "pull_request_target" .github/workflows/, then check the ones that checkoutgithub.event.pull_request.headand execute that code. - Fix the root cause, without waiting for v7: remove the fork checkout, or move to the two-workflow pattern. That is the only real protection, independent of the checkout version.
- Anticipate July 16 according to your pinning:
- floating tag (
@v4): the protection arrives on its own, but a pipeline that depended on the dangerous behavior will break that day. Test before. - pinned by SHA: you will not get it automatically, you will have to explicitly move to checkout v7.
- floating tag (
- Reserve
allow-unsafe-pr-checkoutfor the exception: enable it only on a justified case, and track its appearance in PR reviews. - Make the detection continuous: plumber (ISSUE-804), zizmor and poutine spot these dangerous checkouts, so you do not regress.
What should you remember?
- My default reflex: avoid
pull_request_target. The v7 guardrail reduces the risk, it does not make the trigger desirable. actions/checkout@v7refuses by default to checkout the ref of a fork underpull_request_target: the pwn request is blocked natively.- The
allow-unsafe-pr-checkoutinput reopens the door: treat it as a sensitive exception, never as a convenience. - Backport on July 16, 2026 to the supported major versions: floating
tags (
@v4,@v3) will inherit the protection, and some pipelines will break if they depended on the dangerous behavior. - The guardrail replaces neither minimal permissions, nor the fight against injection, nor the two-workflow pattern.
- It is one more good default: audit now, do not endure it.
Where can you dig deeper?
- Sécuriser pull_request_target (the full how-to)
- Attaques supply chain sur GitHub Actions
- Checklist sécurité des workflows GitHub Actions
- GitHub Actions: 15 security pitfalls that expose your pipelines
One last supply chain reflex: beyond your own workflows, evaluate your suppliers. The plumber radar scores the security posture of the libraries and applications you depend on.
By the way, what is your plumber score?