From dcb46356f3fb65dfe065433472d73f5707bd2ce3 Mon Sep 17 00:00:00 2001 From: Tam Nhu Tran Date: Mon, 16 Mar 2026 07:47:59 -0400 Subject: [PATCH] fix(ci): load review prompt from base branch to prevent prompt injection External PRs could modify review-prompt.md to suppress findings or manipulate the reviewer. Now loads prompt via git show from the base branch (origin/dev or origin/main), never from PR-controlled checkout. Also: - Fallback prompt upgraded with adversarial framing and severity output - Use printf instead of echo for content preservation - Expand deep review trigger to all .github/ files (not just workflows/) --- .github/review-prompt.md | 2 +- .github/workflows/ai-review.yml | 21 ++++++++++++--------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/.github/review-prompt.md b/.github/review-prompt.md index 94636aec..94662f94 100644 --- a/.github/review-prompt.md +++ b/.github/review-prompt.md @@ -32,7 +32,7 @@ Calibrate review depth based on PR scope. DO NOT give a trivial typo fix the sam - Full adversarial analysis across all checklist areas. **Deep review** (ANY of these conditions): -- Files in: auth/, middleware/, security/, crypto/, commands/, shared/, .github/workflows/ +- Files in: auth/, middleware/, security/, crypto/, commands/, shared/, .github/ - New dependencies added (package.json/lockfile changed) - CI/CD workflow files changed - Environment variables added/changed diff --git a/.github/workflows/ai-review.yml b/.github/workflows/ai-review.yml index bd920d69..11235c68 100644 --- a/.github/workflows/ai-review.yml +++ b/.github/workflows/ai-review.yml @@ -184,20 +184,23 @@ jobs: - name: Load review prompt id: review-prompt + env: + CONTRIBUTOR_SOURCE: ${{ needs.prepare.outputs.contributor_source }} + BASE_REF: ${{ github.base_ref || 'dev' }} run: | - PROMPT_FILE=".github/review-prompt.md" - if [ ! -f "$PROMPT_FILE" ]; then - echo "::warning::.github/review-prompt.md not found — using fallback prompt" - PROMPT_FILE="" + # Always load prompt from base branch to prevent PR-controlled prompt injection. + # External PRs could modify review-prompt.md to suppress security findings. + PROMPT_CONTENT="" + git fetch origin "$BASE_REF" --depth=1 2>/dev/null || true + PROMPT_CONTENT=$(git show "origin/${BASE_REF}:.github/review-prompt.md" 2>/dev/null || echo "") + if [ -z "$PROMPT_CONTENT" ]; then + echo "::warning::.github/review-prompt.md not found on base branch ${BASE_REF} — using fallback" + PROMPT_CONTENT="You are a red-team code reviewer. Find every way this code can fail, be exploited, or produce incorrect results. Flag security issues, logic errors, missing error handling, race conditions, and injection risks. Follow the repository CLAUDE.md for project-specific guidelines. Output findings grouped by severity: High (must fix), Medium (should fix), Low (track). Use strict approval criteria." fi DELIMITER="REVIEW_PROMPT_$(openssl rand -hex 16)" { echo "content<<${DELIMITER}" - if [ -n "$PROMPT_FILE" ]; then - cat "$PROMPT_FILE" - else - echo "Perform a thorough code review. Flag security issues, logic errors, and missing error handling. Follow the repository CLAUDE.md for project-specific guidelines." - fi + printf '%s\n' "$PROMPT_CONTENT" echo "${DELIMITER}" } >> "$GITHUB_OUTPUT"