Skip to content

Commit 0dfb0d8

Browse files
committed
fix: read recipe files from base branch to prevent prompt injection
Recipe files define the agent's prompt. When using pull_request_target, the fork's HEAD is checked out, so a malicious fork could craft recipe files to exfiltrate API secrets via prompt injection. Fix by adding a second sparse checkout from the base branch for .agents/recipes/ and reading prompts from there instead of the fork tree.
1 parent 181c637 commit 0dfb0d8

1 file changed

Lines changed: 14 additions & 2 deletions

File tree

.github/workflows/agentic-ci-pr-review.yml

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,16 @@ jobs:
129129
ref: ${{ steps.head.outputs.sha }}
130130
fetch-depth: 0
131131

132+
# SECURITY: Recipe files define the agent's prompt. Always read them
133+
# from the base branch so a fork PR cannot inject malicious instructions
134+
# while API secrets are in scope.
135+
- name: Checkout base branch recipes
136+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
137+
with:
138+
ref: ${{ github.event.pull_request.base.sha || 'main' }}
139+
sparse-checkout: .agents/recipes
140+
path: base-recipes
141+
132142
- name: Pre-flight checks
133143
env:
134144
ANTHROPIC_BASE_URL: ${{ secrets.AGENTIC_CI_API_BASE_URL }}
@@ -169,8 +179,10 @@ jobs:
169179
set -o pipefail
170180
171181
# Build the prompt from _runner.md + recipe, substituting template vars.
172-
RUNNER_CTX=$(cat .agents/recipes/_runner.md)
173-
RECIPE_BODY=$(cat .agents/recipes/pr-review/recipe.md \
182+
# Read from base-recipes/ (checked out from the base branch) so fork
183+
# PRs cannot tamper with the agent prompt.
184+
RUNNER_CTX=$(cat base-recipes/.agents/recipes/_runner.md)
185+
RECIPE_BODY=$(cat base-recipes/.agents/recipes/pr-review/recipe.md \
174186
| sed '1,/^---$/{ /^---$/,/^---$/d }')
175187
176188
PROMPT=$(printf '%s\n\n%s\n' "${RUNNER_CTX}" "${RECIPE_BODY}" \

0 commit comments

Comments
 (0)