From 1a747103f3556fc26fa184615c2f6daeac852055 Mon Sep 17 00:00:00 2001 From: Herve Labas Date: Wed, 8 Apr 2026 12:50:18 +0200 Subject: [PATCH] fix(ci): prevent shell injection in claude-code workflow Move github.event.issue.body/title/number and comment.body from inline ${{ }} expansion in the run: script to the step's env: block. GitHub Actions substitutes template expressions into the shell script as literal text before bash runs, so attacker-controlled issue content could escape the quoted string and execute arbitrary commands. Reading the values from the process environment via $ISSUE_BODY etc. avoids re-parsing and closes the injection vector. Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/claude-code.yml | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/claude-code.yml b/.github/workflows/claude-code.yml index 6d6209e1..a5726040 100644 --- a/.github/workflows/claude-code.yml +++ b/.github/workflows/claude-code.yml @@ -25,15 +25,18 @@ jobs: env: ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # Pass attacker-controlled fields via env to avoid shell injection. + # GitHub Actions template expansion (${{ ... }}) is substituted into + # the run script verbatim, so interpolating issue/comment content + # directly would allow command injection. Env vars are expanded by + # bash at runtime and are not re-parsed. + ISSUE_BODY: ${{ github.event.issue.body || github.event.comment.body }} + ISSUE_NUMBER: ${{ github.event.issue.number }} + ISSUE_TITLE: ${{ github.event.issue.title }} run: | # Install Claude Code curl -fsSL https://claude.ai/install.sh | bash - - # Get issue content - ISSUE_BODY="${{ github.event.issue.body || github.event.comment.body }}" - ISSUE_NUMBER="${{ github.event.issue.number }}" - ISSUE_TITLE="${{ github.event.issue.title }}" - + # Create branch name BRANCH_NAME="claude/issue-${ISSUE_NUMBER}"