Repository navigation
Description
Summary
.github/workflows/_build.yml has multiple run: steps that interpolate ${{ github.* }} context data directly into shell scripts. This is the classic GitHub Actions shell injection pattern (CWE-78, OWASP A03).
Found via static scan (semgrep yaml.github-actions.security.run-shell-injection).
Findings
Lines with ${{ github.* }} context interpolation in run: steps:
.github/workflows/_build.yml:55.github/workflows/_build.yml:68.github/workflows/_build.yml:111.github/workflows/_build.yml:123.github/workflows/_build.yml:162
(Plus any I missed — these are the top 5 from the semgrep output.)
Why this matters
Fields like github.event.pull_request.title, github.event.issue.title, github.head_ref, and github.event.comment.body can be attacker-controlled via crafted PR titles, branch names, or comments. When they get interpolated directly into a run: script, the attacker's input becomes shell code.
Impact: code execution on the runner, which typically has access to GITHUB_TOKEN, release signing keys, PyPI publishing credentials, etc.
Remediation pattern
Replace direct interpolation with an intermediate env var:
# Vulnerable:
run: |
echo "Processing ${{ github.event.pull_request.title }}"
# Safe:
env:
PR_TITLE: ${{ github.event.pull_request.title }}
run: |
echo "Processing $PR_TITLE"The env: block treats the value as a plain string; referencing $PR_TITLE in the script goes through normal shell variable expansion which is not vulnerable to injection.
Notes
- A previous scan of this repo (~April 12) flagged similar findings in
.github/workflows/ci.yml. The current findings are in_build.ymlwhich appears to be a newer workflow file — same pattern, different file. - GitHub's own hardening guide recommends this pattern for any
run:step that referencesgithub.*context: https://docs.github.com/en/actions/learn-github-actions/security-hardening-for-github-actions#understanding-the-risk-of-script-injections
Environment
- Scan date: 2026-04-13
- Tool: semgrep (default ruleset, rule:
yaml.github-actions.security.run-shell-injection) - Repo state: HEAD of main as of scan time
Activity
fix: GitHub Actions shell injection in _build.yml (DeusData#247)
dLo999 commentedon Apr 13, 2026
Draft PR opened: #249
Applied the env-var pattern uniformly across all 6 flagged run: steps plus the archive steps that used matrix.* in tar filenames. Zero findings remaining in _build.yml after the fix.
Changes:
.github/workflows/_build.ymlonly.fix: GitHub Actions shell injection in _build.yml (DeusData#249)
fix: GitHub Actions shell injection in _build.yml (DeusData#249)
fix: GitHub Actions shell injection in _build.yml (DeusData#249)
fix: GitHub Actions shell injection in _build.yml (#249)