Fix: Env-mediate expressions in run blocks - #147
Merged
tykeal merged 1 commit intoJul 29, 2026
Merged
Conversation
Copilot started reviewing on behalf of
ModeSevenIndustrialSolutions
July 29, 2026 09:47
View session
There was a problem hiding this comment.
Pull request overview
This PR mitigates zizmor template-injection findings by removing direct ${{ ... }} GitHub expression expansions from run: blocks and instead passing those values into the shell via step env: variables, so the shell only sees data (shell variables) rather than pre-expanded script content.
Changes:
- Added step-level
env:entries that map step outputs to environment variables (with targetedyamllintline-length suppressions where needed). - Updated bash validation logic to reference the new environment variables instead of
${{ steps.*.outputs.* }}insiderun:scripts. - Applied the same pattern to cache-key validation and artifact-path verification steps.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
zizmor's template-injection audit reports GitHub expressions that expand directly inside run blocks. The expansion happens before the shell sees the script, so a value carrying shell syntax becomes code rather than data. Routes each expression through the step environment instead. The value reaches the shell as a variable, and the expansion leaves the script body entirely. The generated names push some lines past the line-length limit, so those lines carry a yamllint directive. Shortening the names was rejected: they are unique only within one env block, so a global rewrite merges distinct variables and leaves dangling references. Lowering the organisation zizmor floor to informational surfaced these; they predate the change and sat below the old threshold. Co-authored-by: Claude <claude@anthropic.com> Signed-off-by: Matthew Watkins <mwatkins@linuxfoundation.org>
ModeSevenIndustrialSolutions
force-pushed
the
fix/zizmor-template-injection
branch
from
July 29, 2026 10:09
f5bc564 to
116f350
Compare
Copilot started reviewing on behalf of
ModeSevenIndustrialSolutions
July 29, 2026 10:09
View session
tykeal
approved these changes
Jul 29, 2026
tykeal
left a comment
Contributor
There was a problem hiding this comment.
🤖 Dependamerge
Approved this pull request ✅
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
zizmor'stemplate-injectionaudit reports GitHub expressions that expand directly insiderun:blocks. The expansion happens before the shell sees the script, so a value carrying shell syntax becomes code rather than data.Each expression now reaches the shell through the step environment instead. These findings predate the change to the organisation
zizmorfloor (low→informational); they were simply below the old threshold.Please review the diff carefully
The transformation is not purely mechanical. Swapping
${{ expr }}for${VAR}changes the quoting rules, because the original was substituted by GitHub before the shell ran and the replacement is an ordinary shell variable. Three contexts silently stop working:var='${{ expr }}'echo 'text ${{ expr }}'cat <<'EOF'…${{ expr }}shellcheckcatches the first two. It does not catch the heredoc case. That one was found inurl-validity-action, where 27 references would have rendered the job summary as variable names instead of results.What was verified before raising this
zizmor --persona auditor --min-severity informational— no findingsactionlint(including shellcheck) — cleanyamllint— cleanurl-validity-action.dependabot.ymlor version-pin comment changes rode alongNote on the generated names
Where
zizmor's names push a line past the length limit, the line carries ayamllint disable-linedirective. Shortening them was rejected: the short forms are unique only within oneenv:block, so a global rewrite merges distinct variables and leaves dangling references — verified by observing exactly that failure.