Use env vars for workflow_run context values in example workflows#1125
Use env vars for workflow_run context values in example workflows#1125
Conversation
There was a problem hiding this comment.
LGTM — straightforward security hardening of example workflows following GitHub Actions best practices.
Extended reasoning...
Overview
This PR modifies two example workflow files (examples/ci-failure-auto-fix.yml and examples/test-failure-analysis.yml) to pass github.event.workflow_run.* context values through env: blocks instead of interpolating them directly into run: shell scripts. It also adds branch name sanitization via tr -cd and quotes $GITHUB_OUTPUT.
Security risks
The changes reduce security risk by eliminating shell injection vectors from branch names containing special characters. No new security risks are introduced. The one bug found (pre-existing structured_output single-quote interpolation) is not introduced by this PR and is noted as a pre-existing issue.
Level of scrutiny
Low scrutiny is appropriate. These are example workflow files, not production code or library source. The changes are mechanical, follow the well-documented GitHub Actions security hardening pattern, and are small in scope (a handful of lines across two files).
Other factors
The changes are consistent and self-contained. The tr -cd sanitization for branch names in ci-failure-auto-fix.yml is a sensible addition since that value is used to construct a git branch name. The PR description clearly explains the motivation and each change.
| WORKFLOW_NAME: ${{ github.event.workflow_run.name }} | ||
| HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }} | ||
| run: | | ||
| OUTPUT='${{ steps.detect.outputs.structured_output }}' |
There was a problem hiding this comment.
🟣 Pre-existing issue: OUTPUT='${{ steps.detect.outputs.structured_output }}' on lines 59, 76, and 89 is directly interpolated into shell using single quotes — the same class of vulnerability this PR fixes for workflow_run values. If Claude's JSON output contains a single quote (e.g., "summary": "It's a flaky test"), the single-quoting breaks shell parsing. Since the PR already adds env: blocks to these steps, consider also passing structured_output via env: for consistency.
Extended reasoning...
What the bug is
In examples/test-failure-analysis.yml, the variable structured_output from the Claude action step is assigned in shell using single-quote interpolation:
run: |
OUTPUT='${{ steps.detect.outputs.structured_output }}'This appears on lines 59, 76, and 89. GitHub Actions evaluates the ${{ }} expression and substitutes the raw value directly into the shell script before bash executes it.
How it manifests
The structured_output is JSON produced by Claude with a schema containing a summary string field. If that string contains a single quote — which is entirely plausible for natural language (e.g., "summary": "It's a flaky test") — the resulting shell line becomes:
OUTPUT='{ "summary": "It's a flaky test" }'The single quote inside It's terminates the single-quoted string prematurely, leaving s a flaky test" }' as unquoted shell text. This causes a shell syntax error at minimum, and in adversarial scenarios could lead to command injection.
Why existing code doesn't prevent it
The JSON schema constrains the structure of the output but not the characters within string fields. Claude can produce any valid string content in the summary field. There is no escaping or sanitization applied between the GitHub Actions expression evaluation and shell execution.
Impact
In practice, the impact is a robustness issue rather than a security vulnerability, since structured_output comes from the repo's own Claude invocation rather than attacker-controlled input like branch names. However, it would cause the workflow to fail unexpectedly when Claude's summary contains apostrophes or single quotes — a common occurrence in English text.
How to fix
Pass structured_output through an environment variable, the same pattern this PR applies to workflow_run values:
env:
STRUCTURED_OUTPUT: ${{ steps.detect.outputs.structured_output }}
run: |
OUTPUT="$STRUCTURED_OUTPUT"This ensures the value is treated as a literal string by the shell regardless of its contents.
Pre-existing status
This pattern existed before this PR and is not introduced or modified by it. However, the PR already touches the env: blocks of these exact steps to add WORKFLOW_NAME and HEAD_BRANCH, so fixing structured_output at the same time would be a natural and low-risk addition for consistency.
There was a problem hiding this comment.
LGTM — straightforward security hardening of example workflows, moving shell-interpolated context values to env vars.
Extended reasoning...
Overview
This PR modifies two example workflow files (examples/ci-failure-auto-fix.yml and examples/test-failure-analysis.yml) to pass github.event.workflow_run.* context values through env: blocks instead of direct ${{ }} interpolation in run: shell scripts. It also adds branch name sanitization via tr -cd, quotes $GITHUB_OUTPUT, and adds a security note to the ci-failure-auto-fix example.
Security risks
This PR reduces security risk. The prior pattern of interpolating workflow_run.head_branch directly into shell scripts was vulnerable to injection via malicious branch names containing shell metacharacters. The new pattern of passing values through environment variables is the approach recommended by GitHub's security hardening guide. The tr -cd sanitization for the branch name used in constructing a new branch name is a reasonable allowlist approach.
Level of scrutiny
Low scrutiny is appropriate. These are example workflow files (not production code), the changes are mechanical and follow a well-established pattern, and the diff is small and easy to verify. Both bug reports flagged are pre-existing issues not introduced by this PR.
Other factors
The two bugs found by the bug hunting system are both pre-existing issues that exist on main and are not introduced or worsened by this PR. The structured_output single-quote interpolation issue was already posted as an inline comment in a previous review run. The comment-vs-retry confidence mismatch is also pre-existing. Neither should block this PR.
Updates the
workflow_run-triggered example workflows to follow GitHub Actions best practices by passinggithub.event.workflow_run.*context values throughenv:blocks rather than interpolating them directly intorun:shell scripts.Changes
examples/ci-failure-auto-fix.ymlhead_branchandrun_idviaenv:instead of inline${{ }}interpolation in therun:block$GITHUB_OUTPUTexamples/test-failure-analysis.ymlhead_branchandworkflow_run.nameviaenv:in the retry and comment stepsWhy
Branch names can contain characters like
$,(,), backticks, and;that have special meaning in shell contexts. Passing these values through environment variables ensures they're treated as literal strings when referenced in shell scripts, which is the pattern recommended by GitHub's security hardening guide for Actions.