Introduction
GitHub has released a critical security update to the official actions/checkout action, effective June 18, 2026, to mitigate a dangerous class of software supply chain attacks known as "pwn request" exploits. These attacks specifically target the risky use of the pull_request_target workflow trigger, allowing adversaries to execute malicious code with elevated repository privileges.
For organizations relying on GitHub Actions for CI/CD pipelines, this represents a critical supply chain vulnerability that demands immediate attention. The attack surface is significant: any repository using pull_request_target with improper checkout configurations could be compromised, allowing attackers to inject malicious code into production builds, exfiltrate secrets, or maintain persistence within the development infrastructure.
Technical Analysis
Affected Products and Components
actions/checkout— All versions prior to the June 18, 2026 security update- GitHub Actions workflows utilizing the
pull_request_targettrigger - Repositories with write-token permissions granted to workflows
- Platform: GitHub.com and GitHub Enterprise Server
Attack Mechanism
The pwn request attack exploits a dangerous combination of GitHub Actions features. The pull_request_target trigger was designed to allow workflows to run in the security context of the base repository (target branch) rather than the contributor's fork. This is intended for scenarios like approving pull requests from external contributors. However, when combined with insecure use of actions/checkout, this becomes a critical vulnerability.
Attack Chain:
- An attacker forks the target repository
- They create a malicious pull request containing compromised workflow files or code
- The
pull_request_targettrigger fires, executing in the base repository's context with full privileges (secrets, write tokens, etc.) - If
actions/checkoutis used without explicit ref specification or checks, it may checkout content influenced by the attacker - Malicious code executes with elevated permissions, enabling:
- Secret exfiltration (GITHUB_TOKEN, deployment keys, cloud credentials)
- Repository modification or destruction
- Supply chain poisoning of artifacts
- Lateral movement to other repositories or environments
The June 2026 update to actions/checkout specifically addresses this by implementing stricter validation and blocking dangerous checkout patterns when combined with pull_request_target. The action now detects when it's being used in a context that could allow untrusted code execution with elevated privileges and fails fast with a clear error message.
Exploitation Status
This attack pattern is actively documented within security research communities and has been confirmed in real-world supply chain compromises. While no specific CVE is assigned (this is a configuration issue rather than a traditional software vulnerability), active exploitation has been observed targeting organizations with misconfigured workflows. The threat is particularly severe for open-source projects accepting external contributions and enterprises managing multiple repositories with automated CI/CD pipelines.
Detection & Response
SIGMA Rules
---
title: GitHub Actions pull_request_target with Risky Checkout Pattern
id: 8f4d2e1c-7b3a-4f5e-9c1d-2a3b4c5d6e7f
status: experimental
description: Detects GitHub Actions workflows using pull_request_target trigger combined with actions/checkout without explicit ref specification
references:
- https://securitylab.github.com/research/github-actions-preventing-pwn-requests/
author: Security Arsenal
date: 2026/06/18
tags:
- attack.initial_access
- attack.t1195.002
- attack.supply_chain
logsource:
product: github
service: audit_log
detection:
selection:
action: 'create'
document_type: 'workflow_file'
content|contains|all:
- 'pull_request_target:'
- 'uses: actions/checkout@'
filter:
content|contains:
- 'ref:'
- 'persist-credentials: false'
condition: selection and not filter
falsepositives:
- Legitimate workflows using pull_request_target with secure checkout configuration
level: high
---
title: GitHub Actions Workflow Execution from Untrusted Fork
id: 9a5e3f2d-8c4b-5d6f-0a1b-3c4d5e6f7a8b
status: experimental
description: Detects workflow runs triggered by pull_request_target from forks that may indicate pwn request attempts
references:
- https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions
author: Security Arsenal
date: 2026/06/18
tags:
- attack.execution
- attack.t1059.004
- attack.supply_chain
logsource:
product: github
service: audit_log
detection:
selection:
action: 'workflow_run'
workflow_triggered_by: 'pull_request_target'
head_repository_fork: 'true'
filter:
actor|re: '^(dependabot|renovate|github-actions)\[bot\]$'
condition: selection and not filter
falsepositives:
- Valid external contribution testing workflows
level: medium
KQL (Microsoft Sentinel / Defender)
// Hunt for suspicious GitHub Actions pwn request patterns
// Requires GitHub Audit Log connector or custom webhook ingestion
let suspiciousWorkflows = GitHubAuditLog
| where Action == "workflow_run"
| where WorkflowTriggeredBy == "pull_request_target"
| where HeadRepositoryFork == "true"
| project TimeGenerated, Actor, Repository, WorkflowName, WorkflowRunId, HeadBranch, BaseBranch, HeadRepository, HeadRepositoryFork;
// Identify workflows using actions/checkout with risky patterns
let checkoutActivity = GitHubAuditLog
| where Action in ("create", "update")
| where DocumentType == "workflow_file"
| where Content contains "actions/checkout@"
| where Content contains "pull_request_target:"
| project TimeGenerated, Actor, Repository, Content, FilePath;
// Check for secure configuration patterns
let insecureCheckouts = checkoutActivity
| where not(Content contains "ref:")
| or not(Content contains "persist-credentials: false")
| project TimeGenerated, Actor, Repository, FilePath, RiskIndicator = "Missing ref or credential isolation";
// Correlate workflow runs with risky configurations
suspiciousWorkflows
| join kind=leftouter insecureCheckouts on Repository
| project TimeGenerated, Actor, Repository, WorkflowName, HeadRepository, HeadBranch, RiskIndicator, RunId = WorkflowRunId
| order by TimeGenerated desc
| extend Alert = "Potential pwn request pattern detected"
Velociraptor VQL
-- Hunt for local Git repositories with GitHub Actions workflows
-- using pull_request_target with potentially risky checkout patterns
LET workflow_files = SELECT FullPath, Mtime
FROM glob(globs="/.github/workflows/*.yml", roots=SourceFiles)
WHERE Mtime > ago(30d)
LET risky_workflows = SELECT FullPath, Mtime, Data
FROM read_file(filenames=workflow_files.Path)
WHERE Data =~ 'pull_request_target:'
AND Data =~ 'uses: actions/checkout@'
AND NOT Data =~ 'ref:\s*(refs|heads|tags)'
SELECT FullPath, Mtime,
"Risk" AS Severity,
"pull_request_target with insecure checkout" AS Finding
FROM risky_workflows
-- Supplement with process activity showing git clone operations
-- that may be related to repository setup/management
SELECT Timestamp, Pid, Ppid, Name, CommandLine, Username, Exe
FROM pslist()
WHERE Name =~ '(git|gh|hub)'
AND CommandLine =~ '(clone|checkout|pull)'
AND Timestamp > ago(7d)
ORDER BY Timestamp DESC
Remediation Script (Bash)
#!/bin/bash
# GitHub Actions Security Hardening Script
# Audits and remediates pull_request_target pwn request vulnerabilities
# Version: 1.0 - June 2026
set -e
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
VULNERABLE_COUNT=0
FIXED_COUNT=0
echo "============================================"
echo "GitHub Actions Security Audit & Remediation"
echo "Date: $(date)"
echo "============================================"
echo ""
# Validate input
if [ -z "$1" ]; then
echo -e "${RED}Error: Repository path required${NC}"
echo "Usage: $0 <repository-path> [--audit|--fix]"
exit 1
fi
REPO_PATH="$1"
ACTION="${2:---audit}"
if [ ! -d "$REPO_PATH/.github/workflows" ]; then
echo -e "${RED}Error: .github/workflows directory not found${NC}"
exit 1
fi
# Function to check and fix a single workflow file
process_workflow() {
local file=$1
local has_pr_target=0
local has_checkout=0
local has_ref=0
local has_persist_false=0
local is_vulnerable=0
# Check for pull_request_target trigger
if grep -q "pull_request_target:" "$file" 2>/dev/null; then
has_pr_target=1
fi
# Check for actions/checkout usage
if grep -q "uses: actions/checkout@" "$file" 2>/dev/null; then
has_checkout=1
fi
# Check for explicit ref (secure pattern)
if grep -A10 "uses: actions/checkout@" "$file" 2>/dev/null | grep -q "ref:"; then
has_ref=1
fi
# Check for persist-credentials: false
if grep -A10 "uses: actions/checkout@" "$file" 2>/dev/null | grep -q "persist-credentials: false"; then
has_persist_false=1
fi
# Determine vulnerability
if [ $has_pr_target -eq 1 ] && [ $has_checkout -eq 1 ]; then
if [ $has_ref -eq 0 ] || [ $has_persist_false -eq 0 ]; then
is_vulnerable=1
fi
fi
if [ $is_vulnerable -eq 1 ]; then
((VULNERABLE_COUNT++))
echo -e "${RED}[!] VULNERABLE: $file${NC}"
echo " - pull_request_target trigger: YES"
echo " - actions/checkout present: YES"
echo " - Explicit ref specified: $([ $has_ref -eq 1 ] && echo 'YES' || echo 'NO')"
echo " - persist-credentials: false: $([ $has_persist_false -eq 1 ] && echo 'YES' || echo 'NO')"
if [ "$ACTION" == "--fix" ]; then
echo -e "${YELLOW}[*] Attempting remediation...${NC}"
# Update actions/checkout to v4 if older version detected
if grep -q "uses: actions/checkout@v[1-3]" "$file" 2>/dev/null; then
sed -i.bak 's|uses: actions/checkout@v[1-3]|uses: actions/checkout@v4|g' "$file"
echo " Updated actions/checkout to v4"
fi
# Add persist-credentials: false if missing after checkout step
if [ $has_persist_false -eq 0 ]; then
# This is a simplified remediation - manual review recommended
sed -i '/uses: actions/checkout@/a\ persist-credentials: false' "$file" 2>/dev/null || true
echo " Added persist-credentials: false (manual review recommended)"
fi
echo -e "${GREEN}[+] Fixed - please review changes${NC}"
((FIXED_COUNT++))
fi
else
if [ $has_pr_target -eq 1 ]; then
echo -e "${GREEN}[+] SECURE: $file${NC}"
fi
fi
}
# Main audit loop
echo "Scanning workflows in: $REPO_PATH"
echo ""
find "$REPO_PATH/.github/workflows" -type f \( -name "*.yml" -o -name "*.yaml" \) 2>/dev/null | while read -r workflow; do
process_workflow "$workflow"
done
echo ""
echo "============================================"
echo "Audit Summary:"
echo " Vulnerable workflows found: $VULNERABLE_COUNT"
echo " Workflows fixed: $FIXED_COUNT"
echo "============================================"
echo ""
if [ $VULNERABLE_COUNT -gt 0 ] && [ "$ACTION" != "--fix" ]; then
echo -e "${YELLOW}Remediation Instructions:${NC}"
echo "1. Run with --fix flag to automatically update actions/checkout versions"
echo "2. Manually review each vulnerable workflow"
echo "3. Add explicit 'ref:' parameter to actions/checkout steps"
echo "4. Set 'persist-credentials: false' when secrets aren't required"
echo "5. Consider whether pull_request_target is necessary for your workflow"
echo ""
echo "For detailed guidance:"
echo "https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions"
fi
echo ""
echo "Official GitHub Advisory:"
echo "https://github.com/actions/checkout/security/advisories"
Remediation
Immediate Actions (Priority 1 - Critical)
-
Update actions/checkout: Immediately update all
actions/checkoutreferences to v4 or later: yaml- uses: actions/checkout@v4
-
Audit Workflows: Identify all workflows using
pull_request_target: bash
grep -r "pull_request_target:" .github/workflows/
- Review Permissions: Audit and minimize GITHUB_TOKEN scopes in workflow files: yaml permissions: contents: read # Minimum required
Configuration Hardening (Priority 2 - High)
-
Secure Checkout Configuration: Never checkout untrusted code when using
pull_request_target: yaml- uses: actions/checkout@v4 with: ref: ${{ github.base_ref }} # Explicit ref to base branch persist-credentials: false # Prevent secrets from being available
-
Branch Protection Rules: Require pull request reviews and status checks before merge
-
Workflow Approvals: Require manual approval for workflows triggered by external contributors
Policy Implementation (Priority 3 - Medium)
-
Implement Secret Scanning: Enable GitHub Advanced Security for automatic secret detection
-
Dependabot for Actions: Enable automated version updates for GitHub Actions: yaml version: 2 updates:
- package-ecosystem: "github-actions" directory: "/" schedule: interval: "weekly"
-
CI/CD Security Reviews: Establish mandatory security review for all workflow modifications
-
Monitoring and Alerts: Configure notifications for:
- New or modified workflow files
- Workflow runs from external forks
- Failed security checks in pipelines
Official Guidance and Deadlines
- GitHub Advisory: https://github.com/actions/checkout/security/advisories
- Security Documentation: https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions
- Effective Date: June 18, 2026 — Update must be applied immediately
For organizations subject to compliance frameworks (NIST CSF, PCI-DSS, HIPAA), this update addresses supply chain security controls (SSCF-08) and should be documented in your change management and vulnerability remediation processes.
Related Resources
Security Arsenal Alert Triage Automation AlertMonitor Platform Book a SOC Assessment platform Intel Hub
Is your security operations ready?
Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.