hermes - 💡(How to fix) Fix ci: harden lint workflow against head_ref script injection [2 pull requests]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Fix Action

Fixed

RAW_BUFFERClick to expand / collapse

Finding

.github/workflows/lint.yml interpolates ${{ github.head_ref }}, ${{ github.base_ref }}, and ${{ github.ref_name }} directly into bash run: blocks in the lint-diff job. GitHub Actions expression interpolation happens before the runner shell parses the script, so a fork PR with a branch name containing $(), backticks, or "-terminating payloads can break out of the surrounding quotes and execute arbitrary shell.

Offending interpolations (current main)

FileLineFieldStep
.github/workflows/lint.yml58github.base_refDetermine base ref
.github/workflows/lint.yml59github.base_refDetermine base ref
.github/workflows/lint.yml113github.head_ref / github.ref_nameGenerate diff summary

Threat model

This is CI hardening, not a private-security advisory:

  • Fork PR GITHUB_TOKENs are read-only on pull_request triggers.
  • The affected job does not read or expose secrets.
  • No mutation of repo state happens in the compromised step.

The realistic blast radius is attacker-controlled compute inside the lint-diff job (the PR-comment payload, lint reports artifact, etc.). Still worth fixing on first sight: once compute is attacker-controlled, exfil and confused-deputy chains open up cheaply.

Recommended fix

Move PR-derived expressions into step-level env: mappings and reference them via bash variable expansion ("$HEAD_REF", "$BASE_REF", "$BASE_REF_INPUT"). This is the pattern GitHub recommends in Security hardening for GitHub Actions → "Using an intermediate environment variable".

Add a regression test that parses .github/workflows/lint.yml and asserts the lint-diff job's run: blocks contain no ${{ github.head_ref|base_ref|ref_name|event.(pull_request|issue|comment).* }} interpolations.

Scope

Just lint.yml for now — a repo-wide grep of github.(head_ref|base_ref|ref_name) against .github/workflows/ returns matches only in this file. A cross-workflow invariant test is worth doing separately.

References

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - 💡(How to fix) Fix ci: harden lint workflow against head_ref script injection [2 pull requests]