Skip to content

fix: prevent shell injection via workflow_dispatch BASELINE input - #133

Merged
ivanasabi merged 2 commits into
mainfrom
fix/ci-baseline-input-injection
Oct 1, 2026
Merged

ivanasabi merged 2 commits into
mainfrom
fix/ci-baseline-input-injection

Conversation

@ivanasabi

Copy link
Copy Markdown
Contributor

Summary

code-deploy.yml interpolated the workflow_dispatch input BASELINE directly into a run: block. A user with dispatch permission could inject shell metacharacters and, given the job holds id-token: write and all Azure deployment secrets, achieve arbitrary command execution on the runner.

 - name: Get input parameters
+  env:
+    BASELINE: ${{ github.event.inputs.BASELINE || 'main' }}
   run: |
-    BASELINE_BRANCH=${{ github.event.inputs.BASELINE || 'main' }}
+    if [[ "$BASELINE" =~ ^[A-Za-z0-9][A-Za-z0-9._/{}-]*$ ]]; then
+      BASELINE_BRANCH="${BASELINE#refs/heads/}"
+      echo "BASELINE_BRANCH=$BASELINE_BRANCH" >> "$GITHUB_ENV"
+    else
+      echo "::error::invalid BASELINE branch: must contain only letters, digits, or one of . _ / { } -" >&2
+      exit 1
+    fi

The input now travels through env: (no shell interpretation), is quoted at use, and is validated against a strict branch-name regex before anything runs.

Evidence

Validation regex checked offline against injection payloads:

PASS: main | refs/heads/main | release/1.2.3 | feature_FIX | v1.0.0
FAIL: a;rm -rf / | a&&echo | a`id` | a$(id) | a|b | cur${IFS} | a b | ;whoami

Pre-commit ran eslint and commitlint green. YAML parses cleanly; the only remaining github.event.inputs.BASELINE occurrence is the safe env: mapping.

Merge Danger

Door: two-way (worst case: revert the commit / re-run dispatch)

Blast Radius: CI-only

Guards dispatch runs only; normal behavior (default main, refs/heads/ prefix stripped) is unchanged. Legitimate branch names with shell metacharacters outside the allowed set would now be rejected at job start, before Azure login.

Pass BASELINE through env: instead of interpolating it directly into
a run: block, quote it, and validate its format before any Azure
login, build or deploy runs. The job holds id-token: write plus
deployment secrets, so an attacker-controlled dispatch value could
previously achieve arbitrary command execution on the runner.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@ivanasabi
ivanasabi requested a review from a team as a code owner October 1, 2026 19:35
@sonarqubecloud

sonarqubecloud Bot commented Oct 1, 2026

Copy link
Copy Markdown

@ivanasabi
ivanasabi merged commit 8ebd332 into main Oct 1, 2026
11 checks passed
@ivanasabi
ivanasabi deployed to azure-develop October 1, 2026 20:32 — with GitHub Actions Active

This branch was successfully deployed

1 active deployment
azure-develop — ba1c0bcf Deployed Oct 1, 2026 by ivanasabi via Deploy to Container Apps #497
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant