Skip to content

fix(security): pull_request_target vulnerabilities and expression injection - #7

Merged
rafataveira merged 1 commit into
masterfrom
fix/remove-pull-request-target-vulnerability
Mar 3, 2026
Merged

fix(security): pull_request_target vulnerabilities and expression injection#7
rafataveira merged 1 commit into
masterfrom
fix/remove-pull-request-target-vulnerability

Conversation

@360rb

@360rb 360rb commented Mar 3, 2026

Copy link
Copy Markdown

Summary

  • Replace pull_request_target with pull_request in adapter-code-coverage.yml and semgrep.yml (CRITICAL)
  • Fix expression injection in cross-repo-issue.yml by moving attacker-controlled inputs to env vars
  • Add fork-detection conditions to skip write operations for fork PRs where tokens are read-only
  • Add explicit permissions blocks for least-privilege

Vulnerabilities Fixed

CRITICAL: adapter-code-coverage.yml and semgrep.yml

Both workflows use pull_request_target and check out the fork PR code:

ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}

Then execute untrusted code:

  • adapter-code-coverage.yml: Runs go test, loads JS via require() from PR code, has contents: write + pull-requests: write
  • semgrep.yml: Runs semgrep, loads JS via require() from PR code, has pull-requests: write

An attacker can modify .github/workflows/helpers/pull-request-utils.js in their fork PR to exfiltrate the write-access GITHUB_TOKEN, enabling full repository takeover.

LOW: cross-repo-issue.yml (expression injection)

${{ github.event.pull_request.title }} used directly in a run: block without sanitization. A malicious PR title could execute arbitrary shell commands. This only fires on merged PRs (requiring maintainer approval), but is still a defense-in-depth issue.

Reference

This is the exact attack vector exploited by hackerbot-claw as documented by StepSecurity.

Changes

File Severity Change
adapter-code-coverage.yml CRITICAL pull_request_target -> pull_request, pin to head.sha, fork-check on write ops
semgrep.yml CRITICAL pull_request_target -> pull_request, pin to head.sha, fork-check on write ops
cross-repo-issue.yml LOW Move pull_request.title to env var, add permissions block

Behavioral changes

  • Same-repo PRs: No change in behavior
  • Fork PRs: Coverage reports and semgrep comments will not be posted (tokens are read-only for forks), but the checks themselves still run and report pass/fail correctly
  • cross-repo-issue.yml: Retains pull_request_target (necessary for secrets access on merged PRs), but expression injection is fixed

Test plan

  • Verify adapter-code-coverage check runs on a same-repo PR touching adapters/
  • Verify semgrep check runs on a same-repo PR touching adapters/
  • Verify cross-repo issue creation still works when a PR is merged
  • Confirm fork PRs trigger checks without errors (write steps are skipped)

🤖 Generated with Claude Code

…ction

Multiple workflows are vulnerable to the "pwn request" attack documented by
StepSecurity (https://www.stepsecurity.io/blog/hackerbot-claw-github-actions-exploitation).

CRITICAL - adapter-code-coverage.yml and semgrep.yml:
Both use pull_request_target and check out fork PR code via head.ref +
head.repo.full_name, then execute it (go test, semgrep, actions/github-script
loading JS from the PR). This grants attackers write access to the repo token,
enabling full repository takeover.

Fix: Switch to pull_request trigger, pin checkout to head.sha instead of
head.ref, and add fork-detection conditions to skip write operations
(coverage push, PR comments) for fork PRs where the token is read-only.

LOW - cross-repo-issue.yml:
Uses pull_request_target legitimately (needs secrets, only fires on merged PRs)
but has expression injection: github.event.pull_request.title used directly
in a run: block. A malicious PR title could execute arbitrary commands.

Fix: Move PR title and other event data to env vars. Add permissions block.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@360rb 360rb changed the title security: fix pull_request_target vulnerabilities and expression injection fix(security): pull_request_target vulnerabilities and expression injection Mar 3, 2026
@rafataveira
rafataveira merged commit ac77fec into master Mar 3, 2026
5 of 6 checks passed
@rafataveira
rafataveira deleted the fix/remove-pull-request-target-vulnerability branch March 3, 2026 21:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants