From 65030edc661e4839df843925ad5ce2571305ecce Mon Sep 17 00:00:00 2001 From: Bogdan Truta Date: Thu, 1 Oct 2026 13:34:50 +0000 Subject: [PATCH] release.yml: pass the tag through env, not into the shell script Two run steps expanded ${{ github.event.release.tag_name }} (and the repo name) directly into the script text, so a crafted tag name would execute as shell. They now read $TAG / $REPO from env. The build job's checkout also stops persisting the token (persist-credentials: false); it never pushes. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/release.yml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6f712c2..533a8ce 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,11 +18,17 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + with: + persist-credentials: false - uses: actions/setup-python@v5 with: python-version: "3.13" - name: Tag matches __version__ and has a dated CHANGELOG entry - run: python scripts/check_release.py "${{ github.event.release.tag_name }}" + # Event data goes through env, never into the script text: a tag name is + # user-controlled and could otherwise inject shell. + env: + TAG: ${{ github.event.release.tag_name }} + run: python scripts/check_release.py "$TAG" - run: pip install build twine && python -m build - run: twine check --strict dist/* - name: Test the sdist @@ -50,7 +56,9 @@ jobs: - name: Attach the sdist and wheel to the release env: GH_TOKEN: ${{ github.token }} - run: gh release upload "${{ github.event.release.tag_name }}" dist/* --repo "${{ github.repository }}" + TAG: ${{ github.event.release.tag_name }} + REPO: ${{ github.repository }} + run: gh release upload "$TAG" dist/* --repo "$REPO" publish-testpypi: needs: build