From f36052b0ff40ddf38102d0f4a8815560ab10a12e Mon Sep 17 00:00:00 2001 From: Molecule AI Core-DevOps Date: Mon, 11 May 2026 19:35:50 +0000 Subject: [PATCH] fix(ci)(security): revert gate-check-v3 checkout to base SHA (internal#116 footgun) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pull_request_target runs with the repo's secrets-context. Checking out github.event.pull_request.head.sha means a PR that modifies tools/gate-check-v3/gate_check.py executes that modified script with secrets. This is the canonical pull_request_target footgun. Fix: checkout base SHA instead of head SHA for pull_request_target events. Bug-1 (self-loop exclusion) and Bug-3 (403→exit0) from #547 are kept; only the checkout-ref regresses to the pre-#547 base-branch behavior. Refs: #551, internal#116, RFC#324 A4, feedback_pull_request_target_workflow_from_base Co-Authored-By: Claude Opus 4.7 --- .gitea/workflows/gate-check-v3.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/.gitea/workflows/gate-check-v3.yml b/.gitea/workflows/gate-check-v3.yml index 5dad2701..f8d2b42c 100644 --- a/.gitea/workflows/gate-check-v3.yml +++ b/.gitea/workflows/gate-check-v3.yml @@ -40,16 +40,15 @@ jobs: runs-on: ubuntu-latest continue-on-error: true # Never block on our own detector failing steps: - - name: Check out PR branch (head) for the script - # NOTE: we intentionally check out the HEAD/PR branch here — not the base. - # This is required so that script fixes in PR branches (e.g. the self-loop - # exclusion in signal_6_ci) are actually used when evaluating that PR. - # Security: this job runs with continue-on-error: true and does not - # execute arbitrary PR code — it only runs the gate-check script which - # is read-only (API reads + JSON stdout). + - name: Check out BASE ref (never PR-head under pull_request_target) + # pull_request_target runs with repo secrets-context, so checking out + # the PR HEAD would execute PR-branch gate_check.py with secrets. + # Fix: always load gate_check.py from the trusted base/default ref. + # Bug-1 (self-loop exclusion) + Bug-3 (403→exit0) from #547 are + # kept; only this checkout-ref regresses to pre-#547 behavior. uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: - ref: ${{ github.event.pull_request.head.sha }} + ref: ${{ github.event.pull_request.base.sha || github.ref_name }} - name: Run gate-check-v3 (single PR mode) if: github.event_name == 'pull_request_target' || github.event.inputs.pr_number != ''