Infra Audit5 min readUpdated November 4, 2026

One Workflow Line Hands Your Secrets to Strangers

pull_request_target is the most common GitHub Actions misconfiguration. zizmor flags it. Here is exactly how the leak works.

pull_request_target runs in the base repo context with secrets, but can check out the PR head. If it does, attacker code runs with production secrets. Pin the checkout to the base ref, or use plain pull_request.

GitHub gives pull_request_target the base repo's context: its secrets, its token permissions. The trigger exists for workflows that need to comment or label on PRs from forks. The trap is the checkout.

The mechanism

GitHub gives pull_request_target the base repo's context: its secrets, its token permissions. The trigger exists for workflows that need to comment or label on PRs from forks. The trap is the checkout.
GitHub gives pull_request_target the base repo's context: its secrets, its token permissions. The trigger exists for workflows that need to comment or label on PRs from forks. The trap is the checkout. If the workflow does actions/checkout with ref pointing at the PR head, it now executes attacker-controlled code inside a context that holds production secrets. The attacker opens a PR that looks harmless, the workflow runs, and the secrets leave in the build output or a network call.

Why it survives review

The workflow file looks reasonable: it tests PRs, which is what you want. The dangerous line is one ref argument. Reviewers read the steps, not the checkout ref. And the workflow only misbehaves on PRs from forks, which rarely happen in testing.
The workflow file looks reasonable: it tests PRs, which is what you want. The dangerous line is one ref argument. Reviewers read the steps, not the checkout ref. And the workflow only misbehaves on PRs from forks, which rarely happen in testing. It is a config line that is correct 99% of the time and catastrophic the other 1%.

The scan

zizmor detects the pattern and rates it. Manual check: grep every workflow for pull_request_target, then for every hit check whether any step references the PR head. Our own repo's CI runs zizmor on every pull request, so a new workflow with this pattern is blocked before merge.
zizmor detects the pattern and rates it. Manual check: grep every workflow for pull_request_target, then for every hit check whether any step references the PR head. Our own repo's CI runs zizmor on every pull request, so a new workflow with this pattern is blocked before merge.

If it stays

Every fork PR becomes a free attempt at your secrets, and open-source repos get fork PRs constantly. The exposure is not hypothetical: it fires the first time someone submits a PR with a malicious build step. Fix is one line: switch to plain pull_request, or pin the checkout to the base ref.
Every fork PR becomes a free attempt at your secrets, and open-source repos get fork PRs constantly. The exposure is not hypothetical: it fires the first time someone submits a PR with a malicious build step. Fix is one line: switch to plain pull_request, or pin the checkout to the base ref. Then re-run zizmor and expect the finding gone.

4 Tips to Get Started

1

Search your workflows for pull_request_target. Every hit needs a reason.

2

If the workflow checks out github.event.pull_request.head, attacker code runs with your secrets. That is the leak.

3

Use plain pull_request for code checks: it runs the PR's workflow version, without secrets.

4

Run zizmor on the repo. It detects this and the other top Actions misconfigurations.

Ready to Stop Worrying About Infra?

Knowledge is the first step. Get a free 1-hour diagnostic and see where your infrastructure leaks time, money, and focus.

R

Ron Cohen — DevOps engineer & founder, roqy.io

Content reviewed by the roqy.io team. Our guides are based on publicly available data.

Disclaimer: This content is for informational and educational purposes only. It does not constitute professional advice or a guarantee of specific results. Infrastructure needs vary by team, stack, and stage. Consult a qualified engineer for advice tailored to your situation.

Frequently Asked Questions

What is pull_request_target and why is it dangerous?

A GitHub Actions trigger that runs a workflow from the base repository, with its secrets, on code from a fork's pull request. If the workflow checks out the PR head, attacker-controlled code runs with production secrets. It is the most common Actions misconfiguration; zizmor flags it.

When is pull_request_target safe?

When it never checks out the PR head: labelers, greetings, comment bots that only act on metadata. The danger is any checkout of github.event.pull_request.head.sha or a build step that executes PR code. Then the secrets in the base repo context are one script away.

How do I scan my workflows for this?

Run zizmor on the repository. It detects pull_request_target misuse, excessive permissions, template injection, unpinned actions and credential exposure. It runs locally with no credentials and is what mature teams gate their CI with.

Get the DevOps Ecosystem Behind You

One accountable engineer. Full platform behind him. Month-to-month, no lock-in.