From 0bd22e43812cafd15da0e0043e23343de3f4cfcd Mon Sep 17 00:00:00 2001 From: olaservo Date: Tue, 18 Aug 2026 18:56:40 -0700 Subject: [PATCH 1/2] ci: prevent shell injection in status-check workflow The "Get PR number" step interpolated github.event.workflow_run.head_branch directly into a run: script. A PR author controls their branch name, so a name like rce$(...) executes arbitrary commands on the runner, which has a GITHUB_TOKEN with statuses:write and checks:write. Pass the branch name, event name, and PR number through env: and reference them as quoted shell variables so untrusted input is never templated into the script body. Fixes code scanning alert #1 (actions/code-injection/critical). Co-Authored-By: Claude Opus 4.8 --- .github/workflows/status-check.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/status-check.yml b/.github/workflows/status-check.yml index d47e352..21a2aca 100644 --- a/.github/workflows/status-check.yml +++ b/.github/workflows/status-check.yml @@ -28,14 +28,17 @@ jobs: - name: Get PR number id: pr run: | - if [ "${{ github.event_name }}" == "workflow_run" ]; then - PR_NUMBER=$(gh pr list --head "${{ github.event.workflow_run.head_branch }}" --json number --jq '.[0].number') + if [ "$EVENT_NAME" == "workflow_run" ]; then + PR_NUMBER=$(gh pr list --head "$HEAD_BRANCH" --json number --jq '.[0].number') echo "number=$PR_NUMBER" >> $GITHUB_OUTPUT else - echo "number=${{ github.event.pull_request.number }}" >> $GITHUB_OUTPUT + echo "number=$PR_NUMBER_INPUT" >> $GITHUB_OUTPUT fi env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + EVENT_NAME: ${{ github.event_name }} + HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }} + PR_NUMBER_INPUT: ${{ github.event.pull_request.number }} - name: Get changed files id: changed-files From 23ff08b61613b17e21ea87c48c89f1b347d6b962 Mon Sep 17 00:00:00 2001 From: olaservo Date: Wed, 19 Aug 2026 10:21:11 -0700 Subject: [PATCH 2/2] ci: drop unused Get PR number step The step's number output was never read by any other step. The Check required statuses step derives its ref from head.sha / head_sha in the event payload, not from a PR number. Removing the step also removes the shell-injection sink outright (gh pr list --head with an attacker-controlled branch name) instead of only quoting around it. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/status-check.yml | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/.github/workflows/status-check.yml b/.github/workflows/status-check.yml index 21a2aca..42ec4de 100644 --- a/.github/workflows/status-check.yml +++ b/.github/workflows/status-check.yml @@ -25,21 +25,6 @@ jobs: - name: Check out code uses: actions/checkout@v4 - - name: Get PR number - id: pr - run: | - if [ "$EVENT_NAME" == "workflow_run" ]; then - PR_NUMBER=$(gh pr list --head "$HEAD_BRANCH" --json number --jq '.[0].number') - echo "number=$PR_NUMBER" >> $GITHUB_OUTPUT - else - echo "number=$PR_NUMBER_INPUT" >> $GITHUB_OUTPUT - fi - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - EVENT_NAME: ${{ github.event_name }} - HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }} - PR_NUMBER_INPUT: ${{ github.event.pull_request.number }} - - name: Get changed files id: changed-files uses: dorny/paths-filter@v3