Skip to content

Script injection: github.ref_name / github.ref interpolated into shell run: on push path #26

Description

@jiridanek

Summary

action.yml interpolates ${{ github.ref_name }} and ${{ github.ref }} directly into the composite action's run: (shell) block on the non-PR (push / workflow_dispatch) path:

COMMIT_OID="${{ github.sha }}"
REF="${{ github.ref }}"
PR_NUMBER=$(gh pr list \
  --repo "$GITHUB_REPOSITORY" \
  --head "${{ github.ref_name }}" \
  --state open --json number --jq '.[0].number // empty' 2>/dev/null || true)

Because these branch-derived values are interpolated into a shell context, a branch named e.g. foo-$(command) — or one using backticks or a " to break out of the double quotes — results in command execution when a consuming workflow runs on push or workflow_dispatch for that ref.

Impact

Reachable by anyone who can push a branch (or workflow_dispatch) to a repo that uses this action — i.e. it requires write access, so the marginal privilege is limited (such a user can generally already run code in CI). Even so, it's a script-injection footgun in a first-party action: it defeats the usual expectation that uses: of a trusted action is safe, and the injected code runs with whatever token the caller grants (commonly code-quality: write).

Suggested fix

Pass the untrusted values via env: and reference them as quoted shell variables, per GitHub's own hardening guidance (https://docs.github.com/en/actions/security-for-github-actions/security-guidelines/security-hardening-for-github-actions#understanding-the-risk-of-script-injections):

env:
  GH_REF: ${{ github.ref }}
  GH_REF_NAME: ${{ github.ref_name }}
run: |
  REF="$GH_REF"
  PR_NUMBER=$(gh pr list --repo "$GITHUB_REPOSITORY" --head "$GH_REF_NAME" \
    --state open --json number --jq '.[0].number // empty' 2>/dev/null || true)

Version

Observed on v1.4.1 (commit 1c15be3).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions