CVE-2026-3854 is a critical remote code execution vulnerability (CVSS 8.7) in GitHub’s internal git infrastructure affecting both GitHub.com and all GitHub Enterprise Server (GHES) releases prior to the fixed versions. An authenticated attacker with push access to any repository — including one they created themselves — can execute arbitrary commands on the underlying server with a single git push. GitHub.com was patched within 75 minutes of internal validation on March 4, 2026; at the time of public disclosure on April 28, 88% of self-hosted GHES instances remained unpatched.
Background: The babeld Proxy and Push Options
GitHub’s git infrastructure routes push operations through an internal proxy service called babeld. When a user runs git push, babeld collects metadata — repository path, user identity, push options — and forwards it to backend services via a custom HTTP header: X-Stat.
X-Stat uses a semicolon-delimited key=value format:
X-Stat: repo_path=/path/to/repo;user_id=12345;push_option=ci-skip
Git push options (specified with -o) are a standard git feature that lets clients pass arbitrary strings to server-side hooks. They are widely used for CI skip flags, deployment signals, and hook configuration. The problem: babeld copies push option values into X-Stat verbatim, without stripping or escaping semicolons.
How the Injection Works
Because X-Stat uses semicolons as field delimiters, a semicolon embedded in a push option value terminates the current field and begins a new one. Backend services parse X-Stat with last-write-wins semantics: when a key appears more than once, the later value silently overrides the earlier one.
An attacker can inject security-critical internal fields by crafting a push option containing a semicolon:
git push -o 'ci-skip;rails_env=development;custom_hooks_dir=/tmp/evil' origin main
Babeld constructs:
X-Stat: ...;push_option=ci-skip;rails_env=development;custom_hooks_dir=/tmp/evil
The downstream service sees rails_env and custom_hooks_dir as trusted internal fields — indistinguishable from values babeld set legitimately — and acts on them.
Exploitation Chain: Three Fields to Shell
Wiz Research, who discovered and reported the vulnerability, documented a three-stage chain:
Stage 1 — Disable the sandbox. The rails_env field controls whether hook execution runs in a production sandbox or a more permissive development code path. Injecting rails_env=development drops sandbox restrictions.
Stage 2 — Redirect hook lookups. The custom_hooks_dir field sets the base directory from which pre-receive hook scripts are loaded. Pointing it to an attacker-controlled writable path — such as a directory inside a freshly-cloned repository — allows arbitrary hook content to be staged.
Stage 3 — Execute arbitrary code. The repo_pre_receive_hooks field accepts a JSON structure specifying hook binary paths. Combined with path traversal sequences, this resolves to any binary accessible on the filesystem. That binary executes as the git service user when the push is processed.
# Illustrative payload — demonstrates the injection structure
git push \
-o 'ci-skip;rails_env=development;custom_hooks_dir=/tmp/;repo_pre_receive_hooks=[{"path":"../../usr/bin/id"}]' \
origin main
The attack requires nothing beyond a standard git client and push access to one repository. No elevated privileges, no prior foothold, no social engineering.
Impact: Cross-Tenant Exposure at Scale
On GitHub.com’s shared storage infrastructure, the git service user has filesystem read/write access across the storage node handling the push. Wiz confirmed that successful exploitation would expose repositories from multiple unrelated organizations co-hosted on the same node — potentially millions of repositories per compromised storage node.
For GitHub Enterprise Server, the impact is total instance compromise: all hosted repository data, secrets in environment variables, internal service credentials, and GitHub Actions runner registration tokens.
Timeline:
– March 4, 2026, 17:45 UTC — Wiz submits report to GitHub Security
– March 4, 2026, 19:00 UTC — Fix deployed to GitHub.com (75-minute turnaround)
– April 28, 2026 — Coordinated public disclosure; 88% of GHES instances still unpatched at time of disclosure
Patch Verification Checklist for GHES Admins
GitHub.com is already patched and requires no action. If you run GitHub Enterprise Server, work through this checklist now.
Step 1 — Confirm your GHES version
# SSH into your GHES appliance
ghe-version
Alternatively: Management Console → https://\<hostname>:8443 → Settings → About GitHub Enterprise.
Fixed minimum versions by branch:
| Branch | Minimum safe version |
|---|---|
| 3.14 | 3.14.25 |
| 3.15 | 3.15.20 |
| 3.16 | 3.16.16 |
| 3.17 | 3.17.13 |
| 3.18 | 3.18.7 |
| 3.19 | 3.19.4 |
| 3.20 | 3.20.0 |
Any version below the minimum for its branch is vulnerable. Treat an internet-accessible unpatched instance as potentially compromised until upgraded and logs are reviewed.
Step 2 — Scan audit logs for exploit indicators
Semicolons in push option values are the fingerprint of this attack. Search your audit log:
sudo grep -E '"push_option".*"[^"]*;[^"]*"' /var/log/github-audit.log
If your audit log is JSON-formatted, use a targeted query:
sudo python3 -c "
import sys, json
for line in sys.stdin:
try:
entry = json.loads(line)
if ';' in entry.get('push_option', ''):
print(line.strip())
except Exception:
pass
" < /var/log/github-audit.log
Any result warrants manual review. Also check for unusual pre-receive hook execution spikes around the same timestamps:
sudo grep 'pre_receive' /var/log/github/gitauth.log | \
awk -F'T' '{print $1}' | sort | uniq -c | sort -rn | head -20
Step 3 — Rotate instance secrets if exposure is suspected
If your GHES instance was internet-accessible and unpatched for any period after January 2026, rotate:
- GitHub App private keys
- OAuth application client secrets
- Webhook secrets
- SSH host keys (the
gituser has filesystem access to/etc/sshon some GHES configurations) - Credentials stored in environment variables visible to the
gitservice user - GitHub Actions self-hosted runner registration tokens
Step 4 — Add defence-in-depth: reject semicolons in push options
After upgrading, add a server-side pre-receive hook to reject push options containing semicolons at the application layer. This provides a residual defence against similar injection vectors:
#!/bin/bash
# /data/user/repos/custom-hooks/pre-receive
while read oldrev newrev refname; do
for i in $(seq 0 $((GIT_PUSH_OPTION_COUNT - 1))); do
opt=$(eval echo "\$GIT_PUSH_OPTION_$i")
if [[ "$opt" == *';'* ]]; then
echo "Error: push option contains invalid character (semicolon)." >&2
exit 1
fi
done
done
If You Cannot Patch Immediately
Three mitigations reduce exposure while an upgrade window is scheduled:
- Restrict push access — Users with read-only repository access cannot trigger the exploit. Audit push permissions and remove unnecessary grants. This is the most effective short-term control.
- Block external git push at the network layer — Restrict TCP 22 and HTTPS/git to known CIDR ranges if your GHES does not require internet-facing push access.
- Strip push option headers at your reverse proxy — Remove
Git-Push-Option-Countand allGit-Push-Option-Nheaders at the load balancer. This disables push-option-dependent CI workflows but eliminates the injection surface entirely.
Conclusion
CVE-2026-3854 is a textbook trust boundary violation: user-supplied data entered a structured internal protocol without sanitization, and last-write-wins header semantics turned it into a privilege escalation primitive. GitHub’s 75-minute turnaround on GitHub.com is a strong incident response benchmark. The 88% unpatched rate on GHES at disclosure is a reminder that self-hosted deployments carry the full weight of their own patch cycles.
If you manage GitHub Enterprise Server, version verification and audit log review are the immediate actions — not next sprint.
See our analysis of the GlassWorm VS Code supply chain attack for another case study in how developer tooling becomes an attack surface →
Thank you for reading this post, don't forget to subscribe!


Leave feedback about this