prt-scan: AI-Powered GitHub Actions Supply Chain Campaign Exploiting pull_request_target — Threadlinqs Intelligence
As of 2026-05-30, prt-scan: AI-Powered GitHub Actions Supply Chain Campaign Exploiting pull_request_target is a high-severity supply chain threat attributed to prt-scan Operator (N/A), tracked by Threadlinqs Intelligence with 9 detection rules (Splunk SPL, Microsoft KQL, Sigma) and 21 indicators of compromise.
Threat ID: TL-2026-0318 · Severity: HIGH · CVSS: 8.6 · Status: MONITORING · Category: SUPPLY_CHAIN
Attribution: prt-scan Operator · N/A · FINANCIAL
Coordinated supply chain campaign by a single threat actor using 6 GitHub accounts across 6 waves (March 11 - April 3, 2026). Exploits pull_request_target workflow trigger to steal CI/CD secrets,
The prt-scan campaign is a sustained, multi-wave supply chain attack targeting open-source repositories that use GitHub Actions with the pull_request_target workflow trigger. A single threat actor operated 6 disposable GitHub accounts — all registered with Proton Mail addresses using the plus-alias pattern — across 3 weeks from March 11 to April 3, 2026.
The attack methodology is systematic: the actor forks target repositories, creates branches matching the pattern prt-scan-{12-hex-chars}, injects language-aware malicious payloads into CI configuration files (conftest.py for Python, package.json for Node.js, build.rs for Rust, Makefile for Make-based projects, action.yml for GitHub Actions), and opens pull requests with the generic title "ci: update build configuration" and body "Automated build configuration update." When target repositories have pull_request_target workflows that checkout the PR head SHA, the malicious code executes in the privileged workflow context with access to repository secrets.
The payload implements a sophisticated 5-phase exploitation chain:
Phase 1 (EXFIL): Immediately dumps all environment variables and extracts the GITHUB_TOKEN from git HTTP extra headers, encoding output as gzip+base64 between ==PRT_EXFIL_START== and ==PRT_EXFIL_END== markers in CI logs.
Phase 2 (RECON): Enumerates repository and organization secrets via GitHub API endpoints (/actions/secrets, /actions/organization-secrets, /environments), parses workflow YAML files for secrets.XXX references, checks token permissions, downloads recent artifacts, requests OIDC tokens, and probes cloud instance metadata services (AWS IMDS at 169.254.169.254, Azure IMDS, GCP metadata.google.internal).
Phase 3 (DISPATCH): If the stolen token has contents:write and actions:write permissions, creates a temporary workflow file (.github/workflows/.prt_tmp_<nonce>.yml) on the default branch that maps all discovered secrets into environment variables and dispatches it, escalating from reading secret names to exfiltrating actual secret values.
Phase 4 (LABEL_BYPASS): Runs a base64-encoded Python script that parses all workflow YAMLs for pull_request_target label gates, extracts the required label name (defaulting to "safe to test"), creates the label via GitHub API, and applies it to the attacker's own PR — defeating label-based approval gates.
Phase 5 (DELAYED): Launches a background Python daemon that scans /proc/*/environ every 2 seconds for 10 minutes, searching for 22 high-value environment variable keywords including NETLIFY, AWS_SECRET, NPM_TOKEN, CLOUDFLARE, STRIPE, OPENAI, ANTHROPIC, DATABASE_URL, SSH_PRIVATE, and others. Findings are exfiltrated via PR comments wrapped in ==PRT_DELAYED_START== markers, catching secrets injected by later CI steps.
The campaign uses no external command-and-control infrastructure — all exfiltration occurs through GitHub API calls, CI build logs, and PR comments. The actor's User-Agent is consistently python-requests/2.32.5. Payloads are AI-generated and repository-aware, adapting injection vectors to each target's technology stack (pytest hooks for Python repos, npm preinstall scripts for Node.js, cargo build scripts for Rust, .PHONY targets for Make). Some variants use double base64 encoding for obfuscation.
Confirmed compromises include the npm packages @codfish/eslint-config and @codfish/actions (106 malicious versions each published with pattern 0.0.0-PR-{PR#}--{commit}), and darlal/obsidian-switcher-plus where GITHUB_TOKEN and DIFF_ACTION_TOKEN were exposed. High-profile targets include Svelte, Zephyr RTOS, AWS SageMaker Core, Palo Alto Networks pan.dev, SAP open-ux-tools, Red Hat Developer Hub, Sentry, OpenSearch, IPFS, NixOS, Jina AI, recharts, Capstone, and JHipster.
Bot review results were mixed: CodeRabbit flagged all variants as critical, Sourcery AI caught exfiltration and label bypass, Qodo identified 3 critical blocking bugs — but gstraccini auto-approved PRs creating false legitimacy, and C
Weaknesses (CWE)
CWE-829, CWE-494, CWE-352, CWE-269, CWE-200
Target sectors: technology, open-source, cloud-infrastructure, cybersecurity, enterprise-software, financial, iot, embedded-systems, developer-tools, blockchain
Target regions: Global
Detections & IOCs
As of 2026-07-28, this threat has 9 detection rule(s) across Splunk SPL, Microsoft KQL and Sigma, and 21 indicator(s) of compromise. Detection query text and full IOC values are available to authenticated users and programmatically via the Threadlinqs MCP server (Purple tier). View plans.
SUPPLY_CHAIN, HIGH, threat intelligence, cybersecurity, T1585, T1195, T1199, T1059, T1059, T1098, T1543, T1027, T1036, T1656