[MNT] harden the PyPI release workflow against tag-name injection - #10894
Open
WAHIB-EL-KHADIRI wants to merge 1 commit into
Open
[MNT] harden the PyPI release workflow against tag-name injection#10894WAHIB-EL-KHADIRI wants to merge 1 commit into
WAHIB-EL-KHADIRI wants to merge 1 commit into
Conversation
The release tag was expanded directly into the shell body of the tag check. Passing it through env keeps it data. Also declares the least-privilege permissions block the file had never had. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
WAHIB-EL-KHADIRI
requested review from
SimonBlanke,
benHeid,
felipeangelimvieira,
fkiraly,
geetu040,
jgyasu and
marrov
as code owners
August 25, 2026 23:14
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
.github/workflows/wheels.ymlexpands the release tag directly into the shell body of the tag check:A
${{ ... }}expansion is substituted as text before bash parses the line, so a tag containing shell metacharacters is executed rather than compared. Passing it throughenvkeeps it data.This also adds the top-level
permissions: contents: readblock the file had never declared. It matters here becauseupload_wheelscarriesid-token: writefor Trusted Publishing to PyPI — the most valuable token in the repository — and until now every job in the file ran with the default token scope.Severity, stated plainly
Publishing a release requires write access, so this is defense in depth rather than an externally reachable vulnerability. It is worth closing because it removes a step from "can cut a release" to "can run arbitrary code in the workflow that publishes to PyPI".
Note
This is the same class and the same fix as pytorch-forecasting#2385; I found it while reading
wheels.ymlfor a separate reason and it looked worth reporting here too. Kept the diff to the change itself with no explanatory comments in the file, per the review feedback on that PR.One thing I deliberately left out of scope:
pypa/gh-action-pypi-publish@release/v1is a mutable ref rather than a pinned commit SHA. Happy to open that as a separate PR if you want it.Verification
The workflow parses cleanly, no
${{ }}expansion remains in therun:body, andupload_wheelskeeps itsid-token: write. No logic changed.🤖 Generated with Claude Code