GitHub Updates actions/checkout to Block Common Pwn Request Attack Patterns

title: GitHub actions/checkout update: What DevSecOps pros need to know about pull_request_target risk
meta_description: Learn about the recent GitHub actions/checkout security update, pull_request_target exploitation risks, secrets exfiltration, and CI hardening steps to mitigate supply chain threats.
author: Nick Parsons, Principal DevSecOps Engineer
publish_date: 2024-06-16
byline: By Nick Parsons (LinkedIn | GitHub)
TL;DR
- What changed? GitHub's actions/checkout will block untrusted code from forks triggering privileged workflows via pull_request_target. (GitHub announcement)
- Why it matters: Attackers have repeatedly exploited forked PRs to dump secrets via CI workflows—especially when defaults are blindly trusted.
- What to do right now:
- Search your workflows for
pull_request_targettriggers, admin-level GITHUB_TOKEN permissions, and weak self-hosted runner configs. - Set GITHUB_TOKEN permissions to
readin all workflows processing code from forks. - Audit runner IAM roles and segment access.
- Search your workflows for
Immediate Actions
- grep -r pull_request_target .github/workflows/
- gh api /repos/{owner}/{repo}/actions/permissions | jq
- Check for any
permissions: write-allor workflow steps that use secrets on PRs from forks. - Review runner trust boundaries; self-hosted runners should never process untrusted PRs.
Stop Pretending Supply Chain Security Is New
If you’re shocked by the latest GitHub update, you haven’t been paying attention. The writeup from GitHub (Changelog, June 2024) is clear: actions/checkout will refuse to run if a privileged workflow is triggered by a forked PR. This change closes a loophole that criminals have been abusing for years.
Illustrative Example: How Most Teams Get Burned
2AM, fictitious scenario: A PR from a promising fork triggers pull_request_target. The workflow, using default settings, grants a GITHUB_TOKEN with write-all, exposes AWS credentials sitting in env, and executes unchecked code. The attacker siphons off the secrets, leveraging a runner misconfigured with broad IAM policies. Monero mining starts in your cloud. (Illustrative; see GitHub Security Blog for real incidents.)
Anatomy of the Exploit: Step-by-Step
- Attacker forks your repo.
- Creates a PR targeting the base branch.
- Your workflow triggers via
pull_request_target. - actions/checkout runs before code review, using base workflow and GITHUB_TOKEN with elevated permissions.
- Secrets, tokens, environment variables are exposed to the attacker's code.
- Malicious payload exfiltrates secrets.
See official GitHub docs on pull_request_target.
What to Audit Now
- Find risky triggers:
grep -r pull_request_target .github/workflows/
- Locate permissions escalation:
- Check for
permissions: write-allor steps referencing secrets.
- Check for
- Find insecure runner usage:
- Search workflow files for
runs-on: self-hostedor custom runner groups.
- Search workflow files for
Why We Keep Falling for This
Default Configs are Betraying You
GitHub’s default GITHUB_TOKEN gives write permission to repo contents, package registries, and more. Most teams never touch the permissions block; attackers are counting on it (permissions reference).
Workflow Triggers: Trust, Misplaced
pull_request_target is supposed to let you lint external PRs with base branch secrets. In practice, forks can inject arbitrary code and access secrets—especially if workflows combine approval steps and privileged triggers. If you ever see secrets exposed to steps before actual review, fix it.
Runners & IAM: Still Blindly Trusted
Self-hosted runners are often linked to AWS roles with broad policies. Attackers exploit this for privilege escalation—read CVE-2022-21668 for a real GitHub Actions runner exploit.
The Architecture Nightmare: The Fine Print
Threat Model
- Attacker submits PR from a fork.
- Workflow triggers with base branch context, typically via
pull_request_target. - GITHUB_TOKEN defaults grant write-all permission.
- actions/checkout (pre-update) runs attacker code, potentially exposing environment secrets.
Typical Secrets at Risk
- Encrypted secrets in workflow (AWS keys, DB passwords)
- GITHUB_TOKEN (repo-level write)
- Environment variables injected into runner
Why actions/checkout Alone Won’t Save You
Blocking untrusted fork code is a start. But if you let your workflow treat any forked PR as privileged, secrets remain at risk. Here’s how exfiltration usually unfolds:
- PR triggers workflow via pull_request_target (forked source)
- Base workflow runs, actions/checkout spins up
- GITHUB_TOKEN and env secrets exposed to attacker’s code
- Attacker POSTs secrets to external server
Safe Defaults: Fix Your Workflows
Example: Limit GITHUB_TOKEN Permissions
permissions:
contents: read
packages: read
actions: read
Example: Drop Secrets Exposure for Forked PRs
on:
pull_request:
branches:
- main
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Lint code
run: npm run lint
# No secrets passed here
Only Use pull_request_target with Strict Isolation
- Manual approval for privileged steps
- Protect any step that uses secrets, tokens, or state modification

What Modern Security Actually Looks Like
- OIDC for Short-lived Cloud Tokens: Adopt GitHub OIDC and restrict token scopes.
- Runner Isolation: Never let self-hosted runners touch untrusted, external PRs. Segment runners by repo and branch.
- Separate CI for Forks: Route forked PRs through non-privileged CI, reserve secrets for trusted branches only.
- Repository-level Secret Protections: Use protected branches and branch rules to gate sensitive workflows.
Internal: See our blog on Supply Chain Threat Modeling and CI/CD Hardening Best Practices.
How to Check if You’re Affected
-
Find workflows with pull_request_target:
grep -r pull_request_target .github/workflows/
-
Identify write permissions:
- Search for
permissions: write-all - Review workflow steps for secrets usage
- Search for
-
Check runner trust levels:
- No self-hosted runner should process PRs from forks outside your org.
Playbook: Supply Chain CI Triage
- Disable write permissions for GITHUB_TOKEN on all forked PR workflows:
- Set
permissions: readblock in workflow YAML
- Set
- Block merging PRs to protected branches from forks until validated:
- Use branch protection rules, manual review
- Isolate privileged steps behind manual approval:
- Use workflow jobs with
workflow_dispatchor approval checks
- Use workflow jobs with
- Segregate runners:
- Dedicated runners for main, trusted branches only
- Audit for exposed secrets now:
- Use
gh secret list --repo <owner>/<repo>
- Use
Sources & Further Reading
- GitHub actions/checkout security update (Official announcement)
- Critical vulnerabilities in projects powered by GitHub Actions
- CVE-2022-21668: GitHub Actions Runner Privilege Escalation
- Github docs: Permissions for the GITHUB_TOKEN
- Security Hardening with OpenID Connect
- How workflow triggers work
Author
Nick Parsons is a Principal DevSecOps Engineer with 17+ years in CI/CD security. He’s led incident response at Fortune 500s, spoken at Black Hat, and was part of the GitHub Actions IR team post-CVE-2022-21668.
LinkedIn | GitHub
The Kicker
Vendor patches aren’t your airbag—they’re the recall notice after you’ve crashed. If you’re still reading, go rip out your dangerous workflow triggers before someone else does it for you.