# [UNPATCHED] Cli: gh run download implementation allows overwriting git repository configuration upon artifacts downloading

gh run download writes artifact files into .git/, letting a malicious repo drop a .git/commondir redirecting config to attacker-controlled gitconfig for code execution on next git command.

- Payout: $500
- Severity: medium
- Program: GitHub
- Credited: Vladimir Metnew
- Disclosed: 2022-05-04
- Write-up quality: 7/10
- Original: https://github.com/Metnew/write-ups/tree/main/rce-gh-cli-run-download
- Library page: https://bugbountylibrary.com/r/blog%3Agithub-com-metnew-write-ups-tree-main-rce-gh-cli-run-download
- Tags: domain:oss impact:rce kind:bounty platform:blog sev:medium tech:ci-cd technique:chained technique:source-review vuln:misconfiguration vuln:rce

**Target:** gh run download artifact extraction into .git directory
**Root cause:** gh run download extracts artifact files into the current directory with no restriction preventing writes into the .git folder, only a path-traversal check.
**Steps:**
1. Clone malicious repo containing a workflow that uploads an artifact with files named `.git/commondir` and `.git/poc/config`.
2. Run `gh run download` interactively in the repo root; CLI writes artifact files into `.git/`.
3. `.git/commondir` points to `./poc`, so git now uses `.git/poc/config` as the effective config.
4. Run any git command (e.g. `git fetch`) or open the repo in tooling; malicious gitconfig (core.gitproxy, core.sshCommand, credential.helper) executes.
**How found:** Noticed gh run download defaults to writing into the current dir with no restriction on writing into `.git/`, then researched git's commondir mechanism to redirect the effective config.
**Exploitation:** Attacker publishes a repo whose Actions artifact contains `.git/commondir` and a crafted `.git/poc/config` with a malicious core.sshCommand/gitproxy. Victim runs `gh run download` in the repo, then any subsequent git command triggers command execution.
**Escalation:** Alternative via git hooks: commondir redefines core.hooksPath to repo-supplied executable hooks, executing on any porcelain command; currently blocked because upload-artifact strips the +x bit.
**Insight:** When a tool extracts attacker-named files into a working directory, check whether it can write into `.git/`; git's `commondir` lets you swap the entire config (and hooksPath) without touching `.git/config`, so a single dropped file yields RCE on the next git command.
