# Securing GitHub: Wiz Research uncovers Remote Code Execution in GitHub.com and GitHub Enterprise Server (CVE-2026-3854)

Uns sanitized semicolons in git push options let any authenticated user inject X-Stat header fields, chaining to unsandboxed RCE on GitHub.com and GHES.

- Payout: Research
- Severity: critical
- Program: GitHub Enterprise Server
- Credited: Wiz Research
- Disclosed: 2026-04-28
- CVE: CVE-2026-3854
- Write-up quality: 9/10
- Original: https://www.wiz.io/blog/github-rce-vulnerability-cve-2026-3854
- Library page: https://bugbountylibrary.com/r/blog%3Awiz-io-blog-github-rce-vulnerability-cve-2026-3854
- Tags: domain:infra impact:data-leak impact:internal-access impact:rce kind:research platform:threat-intel sev:critical technique:reverse-engineering technique:source-review vuln:command-injection vuln:misconfiguration vuln:path-traversal vuln:rce

**Target:** GitHub internal git push pipeline (babeld, gitrpcd, pre-receive hook binary)
**Root cause:** babeld embeds user-controlled git push option values into the semicolon-delimited X-Stat header without sanitizing ';', and downstream services parse with last-write-wins map semantics, letting attackers override security fields like rails_env, custom_hooks_dir, and repo_pre_receive_hooks.
**Steps:**
1. Authenticate to GitHub/GHES via SSH and target a repo you can push to.
2. Send `git push -o 'x;rails_env=production_disabled;custom_hooks_dir=/tmp;repo_pre_receive_hooks=<json with script path traversal>' origin master`.
3. Injected fields override legitimate X-Stat values due to last-write-wins parsing.
4. Non-production rails_env selects unsandboxed hook execution path; custom_hooks_dir + path traversal in script field resolves to arbitrary binary.
5. Pre-receive binary executes resolved path as git user, yielding RCE (e.g. `id`/`hostname` output in remote:).
6. On GitHub.com, additionally inject the enterprise-mode boolean flag to reach the custom hooks code path.
**How found:** AI-augmented reverse engineering (IDA MCP) of compiled blackbox binaries to reconstruct the internal git push protocol; noticed multi-language services sharing the X-Stat header, hypothesized parser inconsistencies, confirmed injection via binary analysis and packet capture on live GHES, then mapped injectable fields and traced rails_env/custom_hooks_dir/repo_pre_receive_hooks to the unsandboxed hook path.
**Exploitation:** Single git push with crafted -o push options injects X-Stat fields; chained rails_env (bypass sandbox), custom_hooks_dir (redirect lookup base), and repo_pre_receive_hooks (path traversal to arbitrary binary) cause the pre-receive hook to exec the binary unsandboxed as the git service user. On GitHub.com an extra enterprise-mode flag injection was needed to reach the custom hooks path.
**Escalation:** From GHES full server compromise (all repos, internal secrets) to GitHub.com shared storage node compromise, where the git user's broad filesystem permissions exposed millions of repository index entries across tenants.
**Insight:** When multiple services share a delimiter-based internal header with last-write-wins map parsing, look for user input embedded verbatim (e.g. git push options) and try injecting duplicate security-critical keys later in the header to override them; also probe for non-production code paths gated only by an injectable env/flag field.
