fix(ci): prevent template literal injection in repo-health workflow#865
fix(ci): prevent template literal injection in repo-health workflow#865
Conversation
Replace direct steps output interpolation inside actions/github-script script blocks with env: + process.env pattern. This prevents PR output containing backticks or template expressions from being interpreted as JavaScript code. Also hardens heredoc delimiters in GITHUB_OUTPUT by using unique uuidgen-based delimiters instead of static EOF, preventing output injection via early delimiter termination. Changes: - 3x github-script steps: moved step output to env block, read via process.env.STEP_RESULT with nullish coalescing fallback - 4x run steps: replaced static EOF with EOF_uuidgen Closes #769 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
🟢 Impact Analysis — PR #865Risk tier: 🟢 LOW 📊 Summary
🎯 Risk Factors
📦 Modules Affectedci-workflows (1 file)
This report is generated automatically for every PR. See #733 for details. |
🛫 PR Readiness Check
|
| Status | Check | Details |
|---|---|---|
| ✅ | Single commit | 1 commit — clean history |
| ✅ | Not in draft | Ready for review |
| ✅ | Branch up to date | Up to date with dev |
| ❌ | Copilot review | No Copilot review yet — it may still be processing |
| ✅ | Changeset present | No source files changed — changeset not required |
| ✅ | Scope clean | No .squad/ or docs/proposals/ files |
| ✅ | No merge conflicts | No merge conflicts |
| ✅ | Copilot threads resolved | No Copilot review threads |
| ❌ | CI passing | 17 check(s) still running |
This check runs automatically on every push. Fix any ❌ items and push again.
See CONTRIBUTING.md and PR Requirements for details.
🏗️ Architectural Review
Automated architectural review — informational only. |
There was a problem hiding this comment.
Pull request overview
Hardens the Repo Health GitHub Actions workflow against template-literal injection in actions/github-script by ensuring step outputs are treated as data (env vars) rather than interpolated into executable script text.
Changes:
- Move step output consumption in
actions/github-scriptfrom${{ ... }}template-literal interpolation toenv:+process.env. - Replace static
EOFheredoc delimiters used for multiline$GITHUB_OUTPUTvalues with per-step UUID-based delimiters.
| DELIM="EOF_$(uuidgen)" | ||
| echo "result<<${DELIM}" >> $GITHUB_OUTPUT | ||
| echo "$OUTPUT" >> $GITHUB_OUTPUT | ||
| echo "EOF" >> $GITHUB_OUTPUT | ||
| echo "${DELIM}" >> $GITHUB_OUTPUT |
There was a problem hiding this comment.
This step now relies on uuidgen being available on the runner to generate a unique heredoc delimiter. GitHub-hosted runners typically have it, but it’s not guaranteed by the workflow itself; consider using a more universally available source (e.g., /proc/sys/kernel/random/uuid) or explicitly installing the required package to avoid workflow failures. Also consider using printf instead of echo when writing $OUTPUT to $GITHUB_OUTPUT, since echo can treat certain leading values (e.g. -n, -e) as options and mangle the captured output.
| DELIM="EOF_$(uuidgen)" | ||
| echo "result<<${DELIM}" >> $GITHUB_OUTPUT | ||
| echo "$OUTPUT" >> $GITHUB_OUTPUT | ||
| echo "EOF" >> $GITHUB_OUTPUT | ||
| echo "${DELIM}" >> $GITHUB_OUTPUT |
There was a problem hiding this comment.
This step now relies on uuidgen being available on the runner to generate a unique heredoc delimiter. GitHub-hosted runners typically have it, but it’s not guaranteed by the workflow itself; consider using a more universally available source (e.g., /proc/sys/kernel/random/uuid) or explicitly installing the required package to avoid workflow failures. Also consider using printf instead of echo when writing $OUTPUT to $GITHUB_OUTPUT, since echo can treat certain leading values (e.g. -n, -e) as options and mangle the captured output.
| DELIM="EOF_$(uuidgen)" | ||
| echo "result<<${DELIM}" >> $GITHUB_OUTPUT | ||
| echo "$OUTPUT" >> $GITHUB_OUTPUT | ||
| echo "EOF" >> $GITHUB_OUTPUT | ||
| echo "${DELIM}" >> $GITHUB_OUTPUT |
There was a problem hiding this comment.
This step now relies on uuidgen being available on the runner to generate a unique heredoc delimiter. GitHub-hosted runners typically have it, but it’s not guaranteed by the workflow itself; consider using a more universally available source (e.g., /proc/sys/kernel/random/uuid) or explicitly installing the required package to avoid workflow failures. Also consider using printf instead of echo when writing $OUTPUT to $GITHUB_OUTPUT, since echo can treat certain leading values (e.g. -n, -e) as options and mangle the captured output.
| DELIM="EOF_$(uuidgen)" | ||
| echo "result<<${DELIM}" >> $GITHUB_OUTPUT | ||
| echo "$OUTPUT" >> $GITHUB_OUTPUT | ||
| echo "EOF" >> $GITHUB_OUTPUT | ||
| echo "${DELIM}" >> $GITHUB_OUTPUT |
There was a problem hiding this comment.
This step now relies on uuidgen being available on the runner to generate a unique heredoc delimiter. GitHub-hosted runners typically have it, but it’s not guaranteed by the workflow itself; consider using a more universally available source (e.g., /proc/sys/kernel/random/uuid) or explicitly installing the required package to avoid workflow failures. Also consider using printf instead of echo when writing $OUTPUT to $GITHUB_OUTPUT, since echo can treat certain leading values (e.g. -n, -e) as options and mangle the captured output.
|
Closing — superseded by #873 which rewrote the same repo-health.yml file and is now merged into dev. |
Closes #769 - fixes P2 security finding from RETRO audit.
Problem
squad-repo-health.yml injects step outputs directly into actions/github-script script: blocks via JS template literals. If output contains backticks or template expressions, they get interpreted as code.
Fix
Changes