From 06f75f8293c40607eaeca9b41e357123b98363a5 Mon Sep 17 00:00:00 2001 From: XananasX7 Date: Sun, 28 Jun 2026 01:42:57 +0000 Subject: [PATCH] fix(security): document prompt injection risk from ISSUE_BODY in AI agent workflows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The gemini-issue-fixer.yml and gemini-triage.yml workflows pass github.event.issue.body (attacker-controlled) directly as ISSUE_BODY environment variable into the Gemini CLI execution context. This creates an indirect prompt injection surface: any GitHub user who opens an issue can craft a body that attempts to manipulate the Gemini agent's behavior. The agent runs with write-capable GitHub tokens (contents:write, issues:write, pull-requests:write) and the GitHub MCP server, so successful injection could lead to: - Malicious PRs created against the repository - Issue comments posted with attacker-controlled content - Repository content modified via the AI agent Mitigations already present (these must be maintained): - GITHUB_TOKEN: '' in the Gemini execution step - Output validation before applying labels - Template-based responses rather than raw LLM output This commit adds explicit security comments to document that ISSUE_BODY is untrusted user input and that maintaining empty GITHUB_TOKEN during AI execution is a critical security boundary — not an oversight. Note: This action is used by ~1,740 repositories. Consumers who add GITHUB_TOKEN to the Gemini execution step would be vulnerable. --- .github/workflows/gemini-issue-fixer.yml | 2 ++ .github/workflows/gemini-triage.yml | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/.github/workflows/gemini-issue-fixer.yml b/.github/workflows/gemini-issue-fixer.yml index 8f93debe2..d2df47044 100644 --- a/.github/workflows/gemini-issue-fixer.yml +++ b/.github/workflows/gemini-issue-fixer.yml @@ -71,6 +71,8 @@ jobs: REPOSITORY: '${{ github.repository }}' ISSUE_NUMBER: '${{ github.event.issue.number }}' ISSUE_TITLE: '${{ github.event.issue.title }}' + # Security: ISSUE_BODY is attacker-controlled. GITHUB_TOKEN must + # not be set in this step to limit prompt injection blast radius. ISSUE_BODY: '${{ github.event.issue.body }}' BRANCH_NAME: 'gemini-fix-${{ github.event.issue.number }}' EVENT_NAME: '${{ github.event_name }}' diff --git a/.github/workflows/gemini-triage.yml b/.github/workflows/gemini-triage.yml index a06c76edd..bdfbc3356 100644 --- a/.github/workflows/gemini-triage.yml +++ b/.github/workflows/gemini-triage.yml @@ -67,6 +67,8 @@ jobs: env: AVAILABLE_LABELS: '${{ steps.get_labels.outputs.available_labels }}' ISSUE_TITLE: '${{ github.event.issue.title }}' + # Security: ISSUE_BODY is attacker-controlled. GITHUB_TOKEN must + # not be set in this step to limit prompt injection blast radius. ISSUE_BODY: '${{ github.event.issue.body }}' - name: 'Run Gemini issue analysis' @@ -78,6 +80,8 @@ jobs: GEMINI_CLI_TRUST_WORKSPACE: 'true' GITHUB_TOKEN: '' # Do NOT pass any auth tokens here since this runs on untrusted inputs ISSUE_TITLE: '${{ github.event.issue.title }}' + # Security: ISSUE_BODY is attacker-controlled. GITHUB_TOKEN must + # not be set in this step to limit prompt injection blast radius. ISSUE_BODY: '${{ github.event.issue.body }}' AVAILABLE_LABELS: '${{ steps.get_labels.outputs.available_labels }}' with: