Summary
Add actionlint and zizmor as required workflow security validation checks on every PR that touches .github/workflows/**. This prevents recurrence of the script injection class of vulnerability (CWE-78) patched reactively in #350 / PR #351, and remediates the 8 remaining inputs.* interpolation instances across 3 workflow files.
Background
GitHub Actions evaluates ${{ expr }} template expressions server-side before the YAML is handed to the runner shell. When user-controlled values (branch names, PR titles, workflow inputs) are interpolated directly into run: blocks, an attacker can inject shell metacharacters to execute arbitrary commands in the runner context.
PR #351 (fixes #350) patched this in .github/workflows/create-release.yml by moving 4 expressions from inline run: text to step-level env: blocks. The same pattern (inputs.* directly in run:) remains in 3 other workflow files:
| File |
Lines |
Expression |
Risk |
security-deployment.yml |
87, 88, 182, 183, 228 |
inputs.max-age-days, inputs.break-build, inputs.iac-types |
Medium (write access required) |
application-matrix-builds.yml |
172, 178 |
inputs.buildConfig, inputs.securityConfig (JSON blobs) |
High (JSON values embed shell metacharacters) |
resource-provider-pwsh-tests.yml |
78 |
inputs.test-results-output |
Medium (write access required) |
Checkov (CKV_GHA_7) is configured in .checkov.yml with the github_actions framework active and no skips, but it does not produce line-level PR annotations and its CI invocation path is unconfirmed.
Acceptance Criteria
Implementation Notes
Recommended actionlint integration (binary install, no unverified third-party action):
- name: Install actionlint
shell: bash
run: |
ACTIONLINT_VERSION="1.7.12"
curl -sSfL \
"https://github.com/rhysd/actionlint/releases/download/v${ACTIONLINT_VERSION}/actionlint_${ACTIONLINT_VERSION}_linux_amd64.tar.gz" \
-o /tmp/actionlint.tar.gz
tar -xzf /tmp/actionlint.tar.gz -C /tmp actionlint
sudo mv /tmp/actionlint /usr/local/bin/
rm /tmp/actionlint.tar.gz
- name: Run actionlint
shell: bash
run: actionlint -color .github/workflows/*.yml
zizmor SARIF integration:
- name: Run zizmor
shell: bash
run: zizmor --format sarif --output zizmor.sarif . || true
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@<pinned-sha>
with:
sarif_file: zizmor.sarif
category: zizmor
Remediation pattern (same pattern as PR #351):
# Before (vulnerable)
run: |
VALUE="${{ inputs.some-input }}"
# After (safe)
env:
VALUE: ${{ inputs.some-input }}
run: |
echo "$VALUE"
References
Summary
Add
actionlintandzizmoras required workflow security validation checks on every PR that touches.github/workflows/**. This prevents recurrence of the script injection class of vulnerability (CWE-78) patched reactively in #350 / PR #351, and remediates the 8 remaininginputs.*interpolation instances across 3 workflow files.Background
GitHub Actions evaluates
${{ expr }}template expressions server-side before the YAML is handed to the runner shell. When user-controlled values (branch names, PR titles, workflow inputs) are interpolated directly intorun:blocks, an attacker can inject shell metacharacters to execute arbitrary commands in the runner context.PR #351 (fixes #350) patched this in
.github/workflows/create-release.ymlby moving 4 expressions from inlinerun:text to step-levelenv:blocks. The same pattern (inputs.*directly inrun:) remains in 3 other workflow files:security-deployment.ymlinputs.max-age-days,inputs.break-build,inputs.iac-typesapplication-matrix-builds.ymlinputs.buildConfig,inputs.securityConfig(JSON blobs)resource-provider-pwsh-tests.ymlinputs.test-results-outputCheckov (
CKV_GHA_7) is configured in.checkov.ymlwith thegithub_actionsframework active and no skips, but it does not produce line-level PR annotations and its CI invocation path is unconfirmed.Acceptance Criteria
.github/workflows/workflow-lint.ymlis added that runsactionlint v1.7.12against all.github/workflows/*.ymlfilespull_requestandpushtomainwhen paths under.github/workflows/**changezizmor v1.23.1is added to the same workflow to upload SARIF findings to the GitHub Security tab viagithub/codeql-action/upload-sarifinputs.*inrun:patterns are remediated (moved toenv:blocks) so the lint check passes without suppressions, OR each suppression is documented with justificationpr-validation.ymlas a required checkImplementation Notes
Recommended actionlint integration (binary install, no unverified third-party action):
zizmor SARIF integration:
Remediation pattern (same pattern as PR #351):
References