From e2af73abf1d3690e4c0fb7d89c23f3a5522c34ac Mon Sep 17 00:00:00 2001 From: Taimuraz Kaitmazov Date: Fri, 24 Jul 2026 02:03:56 +0300 Subject: [PATCH] ci: check out trusted base in pr-comment, not the fork head_sha The "Comment on PR with Test Results" workflow runs from workflow_run, so it executes in the base repo context with a write-scoped GITHUB_TOKEN and secrets. Its checkout step used ref: github.event.workflow_run.head_sha, which for a fork PR points at the fork's commit. actions/checkout now refuses that: it fails the step with "Refusing to check out fork pull request code from a 'workflow_run' workflow", so the comment job goes red on every fork PR even when the test suites passed. Beyond the false failure, the old behavior is a pwn-request vector. The job's only use of the working tree is running ci/scripts/pretty_aggregate.py; artifacts and PR metadata come from the API. Checking out head_sha meant running the fork author's copy of that script under a token that can write to the repo. A malicious fork could edit the script to exfiltrate the token or push to the base repo. Drop the ref so checkout takes the default branch, i.e. the trusted base copy of the aggregation script. Legitimate PRs get the same comment; the untrusted code no longer runs under the write token. This is the correct fix rather than allow-unsafe-pr-checkout: true, which would keep the hole open. --- .github/workflows/pr-comment.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr-comment.yml b/.github/workflows/pr-comment.yml index 17918e46..e5165f9c 100644 --- a/.github/workflows/pr-comment.yml +++ b/.github/workflows/pr-comment.yml @@ -30,8 +30,13 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 - with: - ref: ${{ github.event.workflow_run.head_sha }} + # No ref: check out the default branch (trusted base code). This job + # runs from workflow_run with a write-scoped GITHUB_TOKEN and secrets, + # so it must not check out the fork's head_sha: actions/checkout now + # refuses that (pwn-request guard), and running the fork's copy of + # ci/scripts/pretty_aggregate.py under the write token would be the + # vulnerability itself. The job only needs the trusted aggregation + # script; artifacts and PR metadata come from the API, not the tree. - name: Set up Python uses: actions/setup-python@v5