Skip to content

Fix: Env-mediate expressions in run blocks - #38

Merged
tykeal merged 1 commit into
lfreleng-actions:mainfrom
modeseven-lfreleng-actions:fix/zizmor-template-injection
Jul 28, 2026
Merged

Fix: Env-mediate expressions in run blocks#38
tykeal merged 1 commit into
lfreleng-actions:mainfrom
modeseven-lfreleng-actions:fix/zizmor-template-injection

Conversation

@ModeSevenIndustrialSolutions

Copy link
Copy Markdown
Contributor

Fix: Env-mediate expressions in run blocks

zizmor --persona auditor reported 14 template-injection findings across the four reusable workflows. This clears all of them; the repository now reports zero findings.

The issue

GitHub expressions were expanded directly inside run: blocks. Expansion happens before the shell sees the script, so the expanded value becomes part of the script text rather than data — a crafted value can inject commands.

This also contradicts a convention docs/BRIEF.md already states:

Never interpolate ${{ }} into run: blocks; env-mediate dynamic values (zizmor template-injection).

So this brings the code into line with the documented design, and with go-workflows / node-workflows, both of which already report zero findings.

Two patterns fixed

1. Release jobs assigning TAG (6 sites — ensure-release, check-promoted, set-promoted-url). These steps already declared an env: block for GH_TOKEN, so the tag simply joins it:

 env:
   GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+  TAG_NAME: ${{ needs.tag-validate.outputs.tag }}
 run: |
-  TAG="${{ needs.tag-validate.outputs.tag }}"
+  TAG="${TAG_NAME}"

2. SBOM summary steps (4 sites × 2 expressions = 8 findings):

+ env:
+   SBOM_COMPONENT_COUNT: ${{ steps.sbom.outputs.component_count }}
+   SBOM_DEPENDENCY_MANAGER: ${{ steps.sbom.outputs.dependency_manager }}
  run: |
-   echo "SBOM count: ${{ steps.sbom.outputs.component_count }}"
-   echo "Tool used: ${{ steps.sbom.outputs.dependency_manager }}"
+   echo "SBOM count: ${SBOM_COMPONENT_COUNT}"
+   echo "Tool used: ${SBOM_DEPENDENCY_MANAGER}"

The multiarch variants already had an env: block for TARGET_ARCH; the new entries join it, leaving the existing $TARGET_ARCH reference untouched.

No behavioural change

The same values reach the same commands. Only the transport changes — expression → environment variable → shell variable, instead of expression → literal script text.

Validation

  • zizmor --persona auditor .github/workflows/"No findings to report." (was 14)
  • Independent check: zero residual ${{ }} expressions inside any run: block across all 9 workflow files
  • pre-commit run --files … — all hooks pass (yamllint, actionlint, workflow schema validation, reuse lint, codespell)

Replacements were applied by an assertion-checked script requiring an exact occurrence count per pattern, so a silent partial match would have failed rather than half-applied.

Note on merge order

This branches from main and touches the same four files as #37 (build egress hatch), though different regions — #37 changes the inputs: block and the python-build job, this changes the sbom/release jobs. They should merge cleanly in either order; if the second one conflicts, it'll be trivial to resolve.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR mitigates GitHub Actions template-injection risk by ensuring GitHub expressions are not interpolated directly into run: script bodies, instead passing dynamic values via env: and then referencing them as shell variables.

Changes:

  • Env-mediate SBOM output values (component_count, dependency_manager) before emitting to $GITHUB_STEP_SUMMARY.
  • Env-mediate validated tag values (tag / tag_name) before using them in release-related gh commands.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
.github/workflows/build-test.yaml Moves SBOM output expressions out of the run: block into env: for the SBOM summary step.
.github/workflows/build-test-release.yaml Env-mediates tag values in release steps and SBOM outputs in the SBOM summary step.
.github/workflows/build-test-release-multiarch.yaml Env-mediates tag values in release steps and SBOM outputs in the multiarch SBOM summary step.
.github/workflows/build-test-multiarch.yaml Moves SBOM output expressions out of the run: block into env: for the multiarch SBOM summary step.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .github/workflows/build-test.yaml Outdated
Comment thread .github/workflows/build-test-release.yaml Outdated
Comment thread .github/workflows/build-test-multiarch.yaml Outdated
Comment thread .github/workflows/build-test-release-multiarch.yaml Outdated
Copilot AI review requested due to automatic review settings July 28, 2026 10:51

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

zizmor's auditor persona reported 14 template-injection findings
across the four reusable workflows: GitHub expressions expanded
directly inside 'run:' blocks, where expansion happens before the
shell sees the script and a crafted value could inject commands.

Pass the values through 'env:' instead and reference them as shell
variables, the convention docs/BRIEF.md already states ("never
interpolate into run: blocks; env-mediate dynamic values") and
which the rest of the repository follows.

Two patterns were affected:

- Release jobs assigning TAG from a tag-validate output, in the
  ensure-release, check-promoted and set-promoted-url steps. Those
  steps already declared an 'env:' block for GH_TOKEN, so the tag
  joins it as TAG_NAME.
- SBOM summary steps echoing the component count and dependency
  manager into the step summary, now read from
  SBOM_COMPONENT_COUNT and SBOM_DEPENDENCY_MANAGER.

No behavioural change: the same values reach the same commands.
Zizmor now reports no findings for the repository.

Co-authored-by: Claude <claude@anthropic.com>
Signed-off-by: Matthew Watkins <mwatkins@linuxfoundation.org>
Copilot AI review requested due to automatic review settings July 28, 2026 13:25

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

@tykeal
tykeal merged commit 9d63aaa into lfreleng-actions:main Jul 28, 2026
72 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants