PT-2025-37421 · Github Actions · Pypa/Gh-Action-Pypi-Publish

Published

2025-09-04

·

Updated

2025-09-04

CVSS v3.1

0.0

None

VectorAV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:N

Summary

gh-action-pypi-publish makes use of GitHub Actions expression expansions (i.e. ${{ ... }}) in contexts that are potentially attacker controllable. Depending on the trigger used to invoke gh-action-pypi-publish, this may allow an attacker to execute arbitrary code within the context of a workflow step that invokes gh-action-pypi-publish.

Details

gh-action-pypi-publish contains a composite action step, set-repo-and-ref, that makes use of expression expansions:
yaml
 - name: Set repo and ref from which to run Docker container action
  id: set-repo-and-ref
  run: |
   # Set repo and ref from which to run Docker container action
   # to handle cases in which `github.action ` context is not set
   # https://github.com/actions/runner/issues/2473
   REF=${{ env.ACTION REF || env.PR REF || github.ref name }}
   REPO=${{ env.ACTION REPO || env.PR REPO || github.repository }}
   REPO ID=${{ env.PR REPO ID || github.repository id }}
   echo "ref=$REF" >>"$GITHUB OUTPUT"
   echo "repo=$REPO" >>"$GITHUB OUTPUT"
   echo "repo-id=$REPO ID" >>"$GITHUB OUTPUT"
  shell: bash
  env:
   ACTION REF: ${{ github.action ref }}
   ACTION REPO: ${{ github.action repository }}
   PR REF: ${{ github.event.pull request.head.ref }}
   PR REPO: ${{ github.event.pull request.head.repo.full name }}
   PR REPO ID: ${{ github.event.pull request.base.repo.id }}
In normal intended operation, these expansions are used to establish a correct priority for outputs like ref and repo-id.
However, these expansions have a side effect: because they're done with ${{ ... }} and not with ${...} (i.e. normal shell interpolation), they can bypass normal shell quoting rules. In particular, if both env.ACTION REF and env.PR REF evaluate to empty strings, then the expression falls back to github.ref name, which can be an attacker controlled string via a branch or tag name.
For example, if the attacker is able to set a branch name to something like innocent;cat${IFS}/etc/passwd, then the REF line may expand as:
bash
REF=innocent;cat${IFS}/etc/passwd
which would set REF to innocent and then run the attacker's code.
Additional information about dangerous expansions can be found in zizmor's template-injection rule documentation.

Impact

The impact of this vulnerability is very low: the expression in question is unlikely to be evaluated in normal operation, since env.ACTION REF should always take precedence.
In particular, the action is not vulnerable in many popular configurations, i.e. those where pull request or release or a push: tags event is used to call the action.

Fix

Command Injection

Found an issue in the description? Have something to add? Feel free to write us 👾

Weakness Enumeration

Related Identifiers

GHSA-VXMW-7H4F-HQXH

Affected Products

Pypa/Gh-Action-Pypi-Publish