# Messing with GitHub's fork collaboration for fun and profit

GitHub fork collaboration access checks diverged across REST/GraphQL/UI endpoints, letting attackers grant themselves write access to others' fork branches.

- Payout: $20,000
- Severity: high
- Program: GitHub
- Credited: Teddy Katz
- Disclosed: 2021-03-10
- CVE: CVE-2021-22861, CVE-2021-22863
- Write-up quality: 8/10
- Original: https://blog.teddykatz.com/2021/03/10/fork-collab-abuse.html
- Library page: https://bugbountylibrary.com/r/blog%3Ablog-teddykatz-com-2021-03-10-fork-collab-abuse-html
- Tags: domain:web impact:integrity kind:bounty platform:blog sev:high tech:graphql tech:rest technique:incomplete-fix technique:source-review vuln:access-control vuln:auth-bypass vuln:privilege-escalation

**Target:** GitHub pull request fork collaboration (REST and GraphQL APIs)
**Root cause:** Fork collaboration permission checks were reimplemented separately across six endpoints (UI/REST/GraphQL create/edit), and the edit paths validated less strictly than create paths, allowing a user to enable maintainer_can_modify without write access to the head branch.
**Steps:**
1. Create a PR from a branch of a victim's fork repository to attacker's repository with fork collaboration disabled.
2. Edit the PR via REST API to set `maintainer_can_modify=true`, bypassing the create-time validation.
3. Victim repo must itself be a fork; attacker then gains write access to the victim's head branch.
4. Second bug: as base-repo maintainer, edit another user's PR via GraphQL API to set maintainer_can_modify, bypassing the author-only check enforced by REST.
**How found:** Curiosity about how the fork-collaboration access grant was implemented; tested creating PRs from others' branches, noticed create-time validation blocked it, then hypothesized edit endpoints might validate less strictly and tested REST then GraphQL edit paths.
**Exploitation:** Attacker creates a PR from a victim's fork branch to their own repo, then PATCHes the PR via REST API to enable fork collaboration, obtaining write access to the victim's branch and ability to tamper with code that maintainers later merge.
**Escalation:** Second GraphQL-only bug allowed base-repo maintainers to override the PR author's refusal to grant branch write access.
**Insight:** When a permission toggle is enforced at resource-creation time, test the update/edit endpoints separately—and test every API surface (REST vs GraphQL vs UI), since each may reimplement the check and drift out of sync.
