Skip to content

[plan] Fix template injection vulnerabilities in 11 workflows #9124

@github-actions

Description

@github-actions

Objective

Secure 16 template injection points across 11 workflows by moving user-controlled input from GitHub Actions expressions to environment variables.

Context

Template injection vulnerabilities occur when untrusted user input (PR titles, issue bodies, comments) is directly interpolated into shell commands via GitHub Actions expressions. This allows attackers to inject arbitrary commands.

Security Impact: While currently marked "Informational", these can escalate to CRITICAL if:

  • Workflows have write permissions
  • Workflows process pull requests from forks
  • User-controlled input reaches sensitive operations

Affected Workflows

Workflow Line Count Severity
changeset.lock.yml 1316 1 Informational
copilot-pr-merged-report.lock.yml 383 2 Informational
daily-performance-summary.lock.yml 811 2 Informational
github-mcp-tools-report.lock.yml 385 1 Informational
mcp-inspector.lock.yml 405 1 Low
metrics-collector.lock.yml 184 1 Informational
schema-consistency-checker.lock.yml 321 1 Informational
smoke-copilot-no-firewall.lock.yml 448 2 Informational
smoke-copilot-playwright.lock.yml 541 2 Informational
smoke-copilot-safe-inputs.lock.yml 429 2 Informational
spec-kit-execute.lock.yml 336 1 Informational

Vulnerable Pattern

# ❌ VULNERABLE - Direct expression interpolation
- name: Process PR
  run: echo "Title: ${{ github.event.pull_request.title }}"

Attack Vector: If PR title is "; malicious command #, the resulting command becomes:

echo "Title: "; malicious command #"

Secure Pattern

# ✅ SECURE - Use environment variables
- name: Process PR
  env:
    PR_TITLE: ${{ github.event.pull_request.title }}
  run: echo "Title: $PR_TITLE"

Fix Approach

Step 1: Identify vulnerable expressions

Search for patterns like:

  • ${{ github.event.issue.title }}
  • ${{ github.event.pull_request.title }}
  • ${{ github.event.comment.body }}
  • ${{ github.event.*.* }} in run: blocks

Step 2: Move to environment variables

For each vulnerable expression:

Before:

- run: |
    echo "Processing: ${{ github.event.issue.title }}"
    ./script.sh "${{ github.event.comment.body }}"

After:

- env:
    ISSUE_TITLE: ${{ github.event.issue.title }}
    COMMENT_BODY: ${{ github.event.comment.body }}
  run: |
    echo "Processing: $ISSUE_TITLE"
    ./script.sh "$COMMENT_BODY"

Step 3: For complex logic, use github-script

- uses: actions/github-script@v7
  with:
    script: |
      const title = context.payload.pull_request.title;
      const body = context.payload.pull_request.body;
      // Safe JavaScript handling
      console.log(`Title: ${title}`);
      // Process safely

Files to Modify

Markdown source files (fix these, then recompile):

  • .github/workflows/changeset.md
  • .github/workflows/copilot-pr-merged-report.md
  • .github/workflows/daily-performance-summary.md
  • .github/workflows/github-mcp-tools-report.md
  • .github/workflows/mcp-inspector.md
  • .github/workflows/metrics-collector.md
  • .github/workflows/schema-consistency-checker.md
  • .github/workflows/smoke-copilot-no-firewall.md
  • .github/workflows/smoke-copilot-playwright.md
  • .github/workflows/smoke-copilot-safe-inputs.md
  • .github/workflows/spec-kit-execute.md

Validation Steps

  1. Fix markdown source file by adding env: blocks
  2. Recompile: make recompile
  3. Run zizmor: zizmor .github/workflows/{workflow}.lock.yml
  4. Verify template injection warnings are resolved
  5. Test workflow doesn't break with edge case inputs

Acceptance Criteria

  • All 16 template injection warnings resolved
  • All 11 affected workflows pass zizmor validation
  • User input moved to environment variables
  • No new vulnerabilities introduced
  • Workflows still function correctly
  • Test with special characters in inputs

Testing

# After fixes
make recompile
gh aw compile --zizmor .github/workflows/{workflow}.md

# Test with malicious input (in a safe environment)
# Create test PR with title: Test"; echo "injected" #

References

AI generated by Plan Command for discussion #9119

Metadata

Metadata

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions