# Code exec on Github runner via Pull request name

GitHub Actions workflow interpolated untrusted PR title into a shell run step, letting a fork PR execute commands and exfiltrate $GITHUB_TOKEN.

- Payout: hidden
- Severity: medium
- Program: Linux Foundation Decentralized Trust
- Found by: another_dude
- Disclosed: 2024-04-28
- Write-up quality: 7/10
- Original: https://hackerone.com/reports/2471956
- Library page: https://bugbountylibrary.com/r/h1%3A2471956
- Tags: area:oss domain:oss impact:internal-access impact:privesc kind:bounty platform:hackerone sev:medium tech:github-actions technique:source-review vuln:command-injection

**Target:** GitHub Actions workflow test_weaver-pre-release.yaml run step
**Root cause:** The workflow interpolated the untrusted `github.event.pull_request.title` (pull_request.name) directly into a double-quoted shell command, so shell metacharacters in the PR title break out and execute.
**Steps:**
1. Fork hyperledger/cacti and create a branch
2. Open a PR titled `U";cat $GITHUB_WORKSPACE/.git/config | xxd -p | base64; echo "D`
3. Wait for the `check_release` workflow (test_weaver-pre-release.yaml) to trigger
4. Read job logs; the base64/xxd encoding bypasses GitHub's `***` masking of the token
5. Decode the leaked $GITHUB_TOKEN from the log
**How found:** Code review of the workflow file spotted untrusted `pull_request.name` interpolated inside double quotes in a run step at line 28.
**Exploitation:** Attacker opens a PR from a fork with a crafted title; the workflow's run step interpolates the title into a double-quoted shell string, executing the injected `cat ... | xxd -p | base64` to exfiltrate the .git config / $GITHUB_TOKEN into public job logs, bypassing secret masking via encoding.
**Escalation:** Leaked $GITHUB_TOKEN could compromise the whole GitHub organization; token is short-lived so the attack must be scripted to complete before the job ends.
**Insight:** When auditing GitHub Actions, grep workflow `run:` blocks for `${{ github.event.pull_request.title }}` and other attacker-controlled context values inside quotes; encode secrets (xxd+base64) to defeat log masking.
