Attackers hid shell commands in GitHub issues to drain CI secrets
Radware found 83 malicious GitHub issues, pull requests and comments across 61 public repos that tricked vulnerable Actions workflows into leaking CI/CD environment variables.
Radware published research on 29 October describing a campaign that hides shell commands inside GitHub issue titles, bodies and comments, hoping a vulnerable Actions workflow will run them automatically. No repository access is needed: posting the issue is enough, because the workflow fires on its own when the event happens.
The firm verified 83 malicious items across 61 public repositories, all posted on 1 September, 77 of them within a 43-minute window. Among the repos hit: Trivy, Brave browser, MLflow, discord.js and cilium. The trick works because some workflows paste event data, such as ${{ github.event.issue.title }}, straight into a shell run: step. Bash performs command substitution on anything inside $(...), even inside double quotes, so a crafted title can run as a command that dumps the job’s environment variables, base64-encodes them and posts them to an attacker-controlled server. Radware confirmed the payload actually executed in at least two cases, including a pull request against PX4-Autopilot, though it could not confirm any specific secrets were retained by the attacker.
Why it matters: this needs no stolen token and no write access, only a GitHub account. If a workflow interpolates untrusted event text directly into a shell step, fix it:
# vulnerable
run: echo "Title: ${{ github.event.issue.title }}"
# safer: pass through an env var, don't interpolate
env:
TITLE: ${{ github.event.issue.title }}
run: echo "Title: $TITLE"
The caveat: Radware disclosed this to affected maintainers, and most repos fixed or closed the reports, but it can’t confirm all of them did. This isn’t a GitHub platform bug GitHub can patch; it’s a workflow pattern, so it remains exploitable anywhere that pattern exists.