Skip to content

security: GitHub Actions shell injection in .github/workflows/_build.yml #247

@dLo999

Description

@dLo999

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.

Reference: https://securitylab.github.com/research/github-actions-untrusted-input/

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

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions