Stealing a few more GitHub Actions secrets ($7500 USD)
I want to say the root of this issue is from trying to determine by name whether an identifier is a commit hash or a branch name. While git allows the creation of branches consisting of 40 hex characters, GitHub will reject the branch. GitHub however, does not reject branch names that copy short-hashes.
Using a047be8
as an example. If that was both a short-hash for a commit, and a branch name, github.com/someone/some-repo/tree/a047be8
would resolve to the branch a047be8
. If that branch were ever deleted then it would resolve to commit. This edge case can lead to an interesting bug.
- Create a branch with a name consisting only of hex characters
- Create a pull-request from another branch to this new branch
- Delete the original branch, causing the PR to be closed
- Create a commit with a short hash matching the branch name (https://github.com/not-an-aardvark/lucky-commit)
- Reopen the PR
Even though the PR is against a non-existent branch, it will resolve to the commit hash instead. Why does this matter? If that commit has a GitHub Action’s workflow, then when the PR is reopened the workflow at the base of the branch of the PR will be run, since that now resolves to the commit, the attackers workflow can be run with access to the GITHUB_TOKEN
for the victim repository.
A lot of steps and user interaction involved with this attack, but its a cool edge case.