Skip to content

Fork PR branch names can no longer run commands on the self-hosted review runner - #36

Merged
wally-tribute-labs merged 1 commit into
mainfrom
security/2026-10-remediation
Oct 26, 2026
Merged

wally-tribute-labs merged 1 commit into
mainfrom
security/2026-10-remediation

Conversation

@wally-tribute-labs

Copy link
Copy Markdown
Collaborator

gate-review.yml interpolated ${{ github.event.pull_request.head.ref }} (the PR branch name) and the PR's label names straight into a run: script. This repo is public, and that job runs on the self-hosted macOS gate-reviewer runner. Anyone could open a fork PR from a branch named something like x";curl …|sh;#, and as soon as a maintainer approved the workflow run, that command would execute on the reviewer machine. Two mitigations were already in place: Actions requires approval for all external contributors, and the runner is offline right now. But the approval click is the only thing standing between a branch name and a shell.

What changed

  • Every event value now reaches the script through env: and is used as a quoted shell variable ("$BRANCH", "$LABELS", …). The Python side already passes the branch to git as an argv list (no shell=True), so the CLI needs no change.
  • Both self-hosted jobs only run for same-repo PRs (head.repo.full_name == github.repository). Fork PRs never reach the runner. To review a fork PR, a maintainer pushes its branch to this repo.
  • test.yml actions are pinned to commit SHAs.

Reviewer notes

  • Fork PRs won't get the gate-review status, so branch protection blocks them until a maintainer pushes the branch here. I think that's the right trade for a public repo with a self-hosted runner.
  • This PR itself needs the gate-reviewer runner online to post its gate-review status.

Verification

  • Both workflow files parse as valid YAML (trigger, cleanup, test jobs intact).
  • No ${{ }} expression remains inside any run: script.
  • The OSV dependency scan of main found nothing in this repo's non-dev dependencies.

Part of the 2026-10 cross-repo security audit remediation.

🤖 Generated with Claude Code

…sted runner

gate-review.yml interpolated ${{ github.event.pull_request.head.ref }}
and PR label names straight into run:, on a public repo whose
pull_request jobs run on the self-hosted macOS gate-reviewer runner. A
fork branch named e.g. `x";curl …|sh;#` would have executed there once
a maintainer approved the run.

- Pass every event value through env: and quote the shell variables.
- Only same-repo PRs reach the self-hosted runner (head.repo ==
  github.repository); fork PRs skip it entirely.
- Pin test.yml actions to commit SHAs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@wally-tribute-labs
wally-tribute-labs merged commit a6cb934 into main Oct 26, 2026
3 of 4 checks passed
@wally-tribute-labs
wally-tribute-labs deleted the security/2026-10-remediation branch October 26, 2026 19:46
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