Back to Intelligence

GitHub Actions Repository Takeover: Detecting and Mitigating 'Pwn Request' Attacks

SA
Security Arsenal Team
July 23, 2026
6 min read

A critical security pattern has re-emerged in 2026 involving GitHub Actions workflows, highlighting a persistent and dangerous vector for supply-chain compromise. Recent analysis of a repository takeover incident involving the cal.com workflows (historically tracked as CVE-2024-58354) provides a stark warning for DevOps teams: CI/CD pipelines remain a primary target for initial access and repository takeover.

The core issue involves the abuse of the pull_request_target trigger. When misconfigured, this trigger allows a workflow to run with elevated, privileged permissions (such as write access to the repository) while executing untrusted code submitted by a malicious actor via a Pull Request. For defenders, this represents a "defense-in-depth" failure where identity and access controls (IAM) within the pipeline are bypassed by workflow logic flaws. This post dissects the mechanics of this attack and provides the detection rules and hardening steps necessary to secure your infrastructure.

Technical Analysis

The Vulnerability Mechanics

The attack vector targets GitHub Actions workflows, specifically those utilizing the pull_request_target event. This event triggers the workflow run in the context of the base commit of the pull request, granting it access to secrets and write permissions that the target branch possesses.

The attack chain observed in recent incidents unfolds as follows:

  1. Trigger: A malicious actor opens a Pull Request against the target repository. The workflow file (e.g., .github/workflows/pr.yml) utilizes on: pull_request_target.
  2. Privilege Escalation: Because the trigger is pull_request_target, the workflow inherits the default GITHUB_TOKEN permissions of the target branch. In insecure configurations, this often includes contents: write.
  3. Dangerous Checkout: The workflow calls a child job or action (e.g., check-types.yml) which performs a checkout of the repository. Critically, it uses a pattern similar to dangerous-git-checkout or standard actions/checkout with explicit ref: ${{ github.event.pull_request.head.sha }} instructions. This fetches the attacker's code, not the trusted base code.
  4. Arbitrary Execution: The workflow proceeds to execute build steps, such as yarn install or npm install. Package managers support lifecycle scripts (e.g., preinstall) defined in package.. Since the package. is controlled by the attacker, the shell command specified in these scripts is executed.
  5. Impact: The script runs with the GITHUB_TOKEN's write scope. The attacker can push malicious code to the repository, steal secrets, or poison the artifact repository.

Affected Components

  • Platform: GitHub Actions
  • Trigger: pull_request_target
  • Risk: Remote Code Execution (RCE) with Repository Write Access
  • Exploitation Status: Proof-of-Concept (PoC) code is widely available in the security community, and automated scanning indicates this misconfiguration is prevalent in open-source and private repositories alike.

Detection & Response

Detecting this attack requires visibility into the CI/CD pipeline execution logs. Defenders should monitor for suspicious command executions originating from build agents that correlate with Pull Request events.

SIGMA Rules

The following rules target suspicious process execution on self-hosted runners or correlate with known dangerous patterns in workflow logs (if ingested into a SIEM).

YAML
---
title: GitHub Actions Suspicious Package Manager Execution
id: 8a2b3c4d-1e2f-3a4b-5c6d-7e8f9a0b1c2d
status: experimental
description: Detects execution of package managers (yarn/npm) triggered by a GitHub Runner that may be processing untrusted PR code. Contextual check for pull request refs is recommended via log correlation.
references:
  - https://securitylab.github.com/research/github-actions-preventing-pwn-requests/
author: Security Arsenal
date: 2026/04/06
tags:
  - attack.execution
  - attack.t1059.004
  - attack.software_supply_chain
logsource:
  category: process_creation
  product: linux
detection:
  selection:
    ParentImage|endswith: '/runner.bin'
    Image|endswith:
      - '/yarn'
      - '/npm'
      - '/node'
  condition: selection
falsepositives:
  - Legitimate build processes for trusted branches
level: high
---
title: GitHub Actions Git Checkout of Pull Request Head
id: 9b3c4d5e-2f3g-4b5c-6d7e-8f9a0b1c2d3e
status: experimental
description: Detects git commands fetching specific pull request heads, which combined with privileged workflows can lead to pwn requests.
references:
  - https://nvd.nist.gov/vuln/detail/CVE-2024-58354
author: Security Arsenal
date: 2026/04/06
tags:
  - attack.initial_access
  - attack.software_supply_chain
logsource:
  category: process_creation
  product: linux
detection:
  selection:
    Image|endswith: '/git'
    CommandLine|contains: 'refs/pull/'
  condition: selection
falsepositives:
  - Valid local testing or trusted automation scripts
level: medium

KQL (Microsoft Sentinel / Defender)

Use this query to hunt for process execution patterns associated with the attack chain on runners monitored by Microsoft Defender for Endpoint or logs ingested via Syslog/CEF.

KQL — Microsoft Sentinel / Defender
// Hunt for suspicious git checkouts and package manager usage on CI runners
let ProcessEvents = DeviceProcessEvents
| where Timestamp > ago(7d);
ProcessEvents
| where FileName in ('yarn', 'npm', 'node', 'git')
| where InitiatingProcessFileName has 'runner' or AccountName has 'runner'
| extend CommandDetails = coalesce(CommandLine, ProcessCommandLine)
| where CommandDetails has 'refs/pull/' 
   or (FileName in ('yarn', 'npm') and CommandDetails has 'install')
| project Timestamp, DeviceName, AccountName, FileName, CommandDetails, InitiatingProcessFileName
| order by Timestamp desc

Velociraptor VQL

This VQL artifact hunts for running processes indicative of a compromise on a build agent.

VQL — Velociraptor
-- Hunt for GitHub Runner executing suspicious git or package management commands
SELECT Pid, Name, CommandLine, Username, CreateTime
FROM pslist()
WHERE Name =~ 'git' 
   AND CommandLine =~ 'refs/pull/'
   OR Name =~ '(yarn|npm)'
   AND Username =~ 'runner'

Remediation Script (Bash)

This script scans a local repository for workflow files that utilize pull_request_target with potentially dangerous permissions or checkout patterns.

Bash / Shell
#!/bin/bash

# Scan for dangerous pull_request_target usage in GitHub Actions
# Usage: ./scan_github_actions.sh /path/to/repo

REPO_DIR="$1"
WORKFLOW_DIR="$REPO_DIR/.github/workflows"

if [ ! -d "$WORKFLOW_DIR" ]; then
  echo "No workflows directory found."
  exit 0
fi

echo "Scanning $WORKFLOW_DIR for potential pwn request vulnerabilities..."

# Find files using pull_request_target
find "$WORKFLOW_DIR" -name "*.yml" -o -name "*.yaml" | while read -r file; do
  if grep -q "pull_request_target" "$file"; then
    echo "[ALERT] Found pull_request_target in: $file"
    
    # Check for default write permissions or write-all
    if grep -q "permissions: write-all" "$file" || grep -q "contents: write" "$file"; then
      echo "  -> [CRITICAL] Workflow grants write permissions."
    fi

    # Check for dangerous checkouts (common vulnerable pattern)
    if grep -q "ref.*pull_request.head.sha" "$file" || grep -q "dangerous-git-checkout" "$file"; then
      echo "  -> [CRITICAL] Workflow checks out untrusted PR code."
    fi
  fi
done

echo "Scan complete."

Remediation

To mitigate this vulnerability, DevOps teams must enforce strict controls over workflow permissions and code execution contexts.

  1. Avoid pull_request_target When Possible: The standard pull_request event is safer because it runs without access to repository secrets and write permissions by default. Only use pull_request_target if you absolutely need to interact with the base branch's secrets or scope.

  2. Explicitly Configure Permissions: Never rely on default token permissions. Explicitly set permissions at the workflow level to the minimum required. yaml permissions: contents: read pull-requests: read

  3. Do Not Check Out Untrusted Code with Privileged Tokens: If using pull_request_target, never check out the PR code (${{ github.event.pull_request.head.sha }}) in the same job that has access to secrets or write tokens.

    • Pattern: Perform a checkout in a separate job with explicitly read-only permissions. If you must run the PR code, run it in a separate, unprivileged job.
  4. Pin Action Versions: Ensure all third-party actions are pinned to a full commit SHA (SHA-1), not a tag or branch, to prevent supply-chain attacks via the action repository itself.

  5. Audit Repository Secrets: Rotate GITHUB_TOKEN and any deployment secrets if you suspect a repository has been vulnerable to this flaw in the past.

Related Resources

Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub

cve-2024-58354criticalcvezero-daypatch-tuesdayexploitvulnerability-disclosuregithub-actionsci-cd-securitysupply-chain

Is your security operations ready?

Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.