Skip to content

Injection warnings from Sonar in generated maintenance workflow #39532

@Artur-

Description

@Artur-

The maintenance-workflow generator emits two Record outputs steps that interpolate workflow inputs directly into a shell run block, which is a GitHub Actions script-injection sink (Sonar githubactions:S7630, CodeQL actions/expression-injection).

In pkg/workflow/maintenance_workflow_yaml.go (main, v0.79.8):

// line 300-302  (run_operation job)
- name: Record outputs
  id: record
  run: echo "operation=${{ inputs.operation }}" >> "$GITHUB_OUTPUT"

// line 403-405  (apply_safe_outputs job)
- name: Record outputs
  id: record
  run: echo "run_url=${{ inputs.run_url }}" >> "$GITHUB_OUTPUT"

${{ }} is expanded before the shell runs, so a crafted input can break out of echo and run arbitrary commands on the runner. run_url is a free-form string on both workflow_dispatch and workflow_call; operation is free-form string on workflow_call. (The jobs gate on a maintainer check, so it is privilege-bounded, but the pattern is still unsafe and flagged BLOCKER.)

Fix — use the env-indirection pattern already applied to the adjacent steps (GH_AW_OPERATION line 290, GH_AW_RUN_URL line 394):

- name: Record outputs
  id: record
  env:
    GH_AW_OPERATION: ${{ inputs.operation }}
  run: echo "operation=$GH_AW_OPERATION" >> "$GITHUB_OUTPUT"
- name: Record outputs
  id: record
  env:
    GH_AW_RUN_URL: ${{ inputs.run_url }}
  run: echo "run_url=$GH_AW_RUN_URL" >> "$GITHUB_OUTPUT"

All downstream consumers of these generated workflows would be fixed on next gh aw compile.

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