🛡️ GHSA-vxmw-7h4f-hqxh — gh-action-pypi-publish
Description
PyPI publish GitHub Action vulnerable to injectable expression expansions in action steps
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 }}
```
Permalink: https://github.com/pypa/gh-action-pypi-publish/blob/db8f07d3871a0a180efa06b95d467625c19d5d5f/action.yml#L114-L125
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](https://woodruffw.github.io/zizmor/audits/#template-injection).
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.
How this vulnerability can be exploited
This issue can be reached over the network, attack complexity is low, an attacker needs no privileges on the target. No user interaction is required. The scope is unchanged, so the impact stays within the vulnerable component. Rated impact: confidentiality none, integrity none, availability none.
Weakness class
GHSA-vxmw-7h4f-hqxh is classified as CWE-77: Command Injection. User input is placed into a command that the system interprets, allowing extra commands to be appended to the intended one.
Affected software
GHSA-vxmw-7h4f-hqxh is recorded against 1 package.
- pypa/gh-action-pypi-publish (fixed in 1.13.0)
Timeline and source
Published on 4 September 2025. No public exploit is currently recorded for this entry. Record sourced from OSV.
References
Details
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:N
Affected Packages
| Software | From version | Fixed in |
|---|---|---|
| pypa/gh-action-pypi-publish | — | 1.13.0 |
References
Free Vulnerability Check
Is your site affected by GHSA-vxmw-7h4f-hqxh?
BotEraser helps you identify potentially vulnerable plugins and themes by checking your installation against GHSA-vxmw-7h4f-hqxh and other known CVE records.
Scan My Site Free →No credit card required · Results in minutes
ⓘ Data Notice: The information presented above has been compiled from publicly available internet sources. Boteraser aggregates this data solely for informational purposes and does not independently classify, evaluate, or endorse any findings about the vulnerabilities listed. The accuracy and completeness of this information is the sole responsibility of the original publishers. Boteraser and its operators accept no liability for any decisions made based on this data.