How a single git push command could have given an attacker access to millions of repositories on GitHub
A standard git push command, the kind developers run dozens of times a day, was all it took to trigger remote code execution on GitHub's infrastructure. No special tools. No elevated permissions. Just a crafted push option containing a few extra semicolons, and an attacker would have landed on a shared server with access to millions of private and public repository index entries belonging to different organizations.
The vulnerability, tracked as CVE-2026-3854, was discovered by security researchers at Wiz on March 4, 2026, and disclosed publicly on April 28, 2026. GitHub patched its own platform within hours of receiving the report and confirmed through forensic investigation that no exploitation occurred before disclosure. But here is the detail that should keep enterprise security teams awake: at the time of public disclosure, 88% of self-hosted GitHub Enterprise Server (GHES) instances remained unpatched, nearly two months after fixes were available. Thousands of enterprise and government deployments were sitting exposed with a known, fully documented exploit path.
The researchers found the vulnerability using AI-augmented reverse engineering tools that allowed them to analyze GitHub's closed-source compiled binaries at a scale and speed that would have been impractical manually. That matters beyond this specific bug: it signals that the historical assumption that proprietary compiled code is hard to audit is no longer reliable.
Narrative Β· 6 min read
The Context
GitHub is the world's largest platform for storing and collaborating on software code. It hosts repositories for individual developers, Fortune 500 companies, government agencies, and open-source projects that underpin global internet infrastructure. Many large organizations run GitHub Enterprise Server, a self-hosted version of GitHub they operate on their own hardware or private cloud, giving them direct control over their source code.
Source code repositories are among the most sensitive assets an organization holds. They contain intellectual property, application logic, secrets that developers accidentally commit, and the build pipelines that produce software shipped to customers. A server hosting all of an organization's repositories is, in practice, a master key to its technical operations.
The Attack, Phase by Phase
Phase 1: AI-Augmented Binary Discovery
The researchers at Wiz used a tool called IDA MCP, which combines a standard binary analysis platform with AI assistance, to read and interpret GitHub's compiled, closed-source software. Because babeld is not open source, there is no human-readable code to inspect. Traditionally, analyzing compiled binaries at this depth required weeks of manual work by specialized reverse engineers.
The AI-augmented approach let the Wiz team reconstruct GitHub's internal X-Stat protocol, map every point where user-supplied input flowed through the git push pipeline, and identify where that input was embedded into internal messages without being cleaned. What would previously have taken weeks took a fraction of that time.
Phase 2: The Injection Mechanism
When a developer runs git push -o with a push option value, that string travels through babeld, which embeds it directly into the X-Stat header. The X-Stat header uses semicolons to separate its fields β a structured list of security instructions passed between GitHub's internal services.
The problem: babeld did not strip or escape semicolons from the user-supplied string before embedding it. An attacker could type a semicolon followed by a field name and value inside their push option, and babeld would copy it into the header as if it were a legitimate server-set field.
Because downstream services used last-write-wins logic, any field the attacker injected would silently overwrite the value the server had already set. The server's own security instructions could be replaced by the attacker's β with no error, no warning, and no indication anything unusual had occurred.
Phase 3: Three-Field RCE Chain
Wiz researcher Sagi Tzadik chained three injected X-Stat fields to achieve full remote code execution:
- Override
rails_env: Controls which environment GitHub's backend runs in. Overriding it to a non-production value bypassed the production security sandbox. - Redirect
custom_hooks_dir: Tells GitHub where to find custom hook scripts that run during git operations. Redirecting it to an attacker-controlled path meant the server would look for scripts in a location the attacker could influence. - Path traversal via
repo_pre_receive_hooks: Specifies which script to execute before accepting a push. Injecting a path traversal payload here forced the server to execute an arbitrary binary as the git service user.
The entire attack was delivered in a single standard git push command. No special client software. No prior compromise of any account beyond basic repository push access.
Phase 4: Disclosure, Patch, and the Unpatched Tail
Wiz reported the vulnerability to GitHub on March 4, 2026. GitHub patched GitHub.com within less than two hours. GHES patches were released on March 10, 2026, across all supported release branches.
GitHub's forensic investigation confirmed no prior exploitation. The exploit forces a code path never used during normal operations, making prior exploitation detectable in logs. Every occurrence of that anomalous path mapped exclusively to the Wiz researchers' own testing.
At public disclosure on April 28, 2026 β nearly two months after fixes were available β Wiz data showed 88% of self-hosted GHES instances had not applied the patches.
What Made This Possible
-
A single unsanitized handoff point invalidated the entire pipeline's trust model. Babeld was the only place where user input needed to be cleaned before entering the X-Stat header. Because it was not, every downstream service inherited the attacker's injected values as legitimate server instructions. The pipeline trusted the header; the header trusted babeld; babeld trusted the user.
-
Last-write-wins parsing turned a formatting quirk into a security control bypass. If downstream services had rejected duplicate fields or used first-write-wins logic, injected fields would have had no effect. The parsing rule that made injection dangerous was a design choice, not an accident.
-
Closed-source infrastructure created a false sense of audit resistance. Because babeld is compiled and proprietary, the assumption was that finding vulnerabilities required impractical effort. AI-augmented reverse engineering has changed that calculus. The obscurity that once provided soft protection no longer holds.
What Should Have Stopped This
No single defense here depends on babeld's own integrity to enforce a security boundary β every effective control sits outside the compromised component.
- Input sanitization at the protocol boundary. Stripping semicolons from push option values before embedding them into the X-Stat header would have made injection impossible regardless of what downstream services did. The fix belongs at the point of entry, not consumption.
- First-write-wins or field-rejection parsing in downstream services. If services consuming the X-Stat header had rejected duplicate fields rather than silently overwriting them, the last-write-wins behavior would not have existed. Defense in depth at the parsing layer would have contained the blast radius even if babeld failed.
- Principle of least privilege for the git service user. The git service user had access to repository index entries across all organizations on a shared node by design. Tighter tenant isolation would have limited what an attacker could reach after gaining code execution.
- Aggressive patch velocity for self-hosted deployments. The 88% unpatched rate is not a GitHub failure; it is an enterprise operations failure. A critical RCE patch sitting unapplied for 49 days is an open invitation.
The Takeaway
This attack is the same class of failure as the Stryker Intune wipe: a trusted internal system was weaponized against the organization it was built to protect because the attacker could supply input the system passed along without scrutiny. The meta-pattern across both incidents is that multi-component pipelines fail when any single component trusts its input more than the pipeline's security model requires.
What is new here is the research method. AI-augmented binary analysis made a closed-source, multi-service architecture auditable at a scale and speed previously impractical. That is not a one-time event β it is a structural shift. Security teams and vendors who have relied on the friction of binary analysis as soft protection need to reckon with that assumption being gone.
Pattern to remember: In a multi-service pipeline, the security of every downstream component is only as strong as the least-sanitizing component upstream.
What changed: AI-augmented reverse engineering has made closed-source compiled binaries auditable at a speed and scale that collapses the practical security gap between proprietary and open-source code, removing obscurity as a meaningful layer of protection for any vendor shipping compiled infrastructure software.
Technical Deep Dive Β· 3 min
The Technical Mechanism
The vulnerability is classified as CWE-77 (Improper Neutralization of Special Elements used in a Command) with CAPEC-248 (Command Injection). The root cause is in babeld, GitHub's closed-source compiled git proxy, which handles all incoming git operations over SSH.
When a client sends git push -o <value>, babeld serializes the push option string directly into the X-Stat internal protocol header using a semicolon-delimited key-value format. The implementation did not apply any sanitization, escaping, or allowlisting to the user-supplied string before embedding it. Because X-Stat uses semicolons as field delimiters, a user-supplied value containing a semicolon followed by a valid field name and value was parsed by downstream services as a legitimate additional field.
Downstream microservices that consumed the X-Stat header applied last-write-wins semantics: if a field appeared multiple times, the final occurrence took precedence. This allowed an attacker to override any field the server had already written into the header by appending an injected duplicate with a higher position in the serialized string.
Wiz researcher Sagi Tzadik constructed the following three-field injection chain to achieve RCE:
- Inject
rails_env=<non-production value>to escape the production application sandbox. - Inject
custom_hooks_dir=<attacker-controlled path>to redirect the hook script lookup location. - Inject
repo_pre_receive_hooks=<path traversal payload>to force execution of an arbitrary binary as thegitservice user.
The attack required no privileges beyond standard repository push access and no user interaction. On GitHub.com, the git service user had filesystem access to repository index entries across all organizations co-hosted on the same shared storage node, meaning a single exploit gave read access to millions of repository index entries belonging to unrelated organizations.
The exploit forces a code path that is never exercised during normal operations, making prior exploitation detectable through log analysis. GitHub confirmed through forensic investigation that no exploitation occurred before responsible disclosure.
CVE and Advisories
CVE-2026-3854: CVSS 4.0 score 8.7 (HIGH); CVSS 3.1 score 8.8 (HIGH). Affects GitHub Enterprise Server3.14.0through3.19.2. Fixed in3.14.24,3.15.19,3.16.15,3.17.12,3.18.6, and3.19.3. Note:3.15.19and3.16.15were subsequently unpublished due to mismatched Git versions between containers; administrators should apply the next available patch release for those branches.- GitHub Enterprise Server Release Notes (3.18): Official patch advisory confirming push options were not properly sanitized before inclusion in internal headers.
- GitHub Security Blog: Securing the git push pipeline: GitHub's official incident response and disclosure post.
MITRE ATT&CK Mapping
| Technique ID | ATT&CK name | How it appeared |
|---|---|---|
| T1190 | Exploit Public-Facing Application | The git push endpoint is a public-facing interface; the injection was delivered through a standard client operation requiring only push access. |
| T1059 | Command and Scripting Interpreter | The three-field injection chain forced execution of an arbitrary binary through the pre-receive hook mechanism, effectively using GitHub's own hook execution as a command interpreter. |
| T1548 | Abuse Elevation Control Mechanism | Overriding rails_env bypassed the production application sandbox, escaping an intended privilege boundary without exploiting a separate privilege escalation vulnerability. |
| T1083 | File and Directory Discovery | On GitHub.com, code execution as the git service user provided access to repository index entries across all organizations on the shared storage node. |
| T1565 | Data Manipulation | The last-write-wins injection silently overwrote server-set security metadata in the X-Stat header, manipulating the data the server used to make authorization decisions. |
Indicators of Compromise
The exploit forces a server-side code path that is never exercised during normal git push operations. GitHub confirmed this property enabled forensic detection: every occurrence of the anomalous code path in GitHub's logs mapped exclusively to the Wiz researchers' own testing activity.
For self-hosted GHES administrators, GitHub advises auditing /var/log/github-audit.log for push operations containing semicolons in push option values. A push option value containing a semicolon followed by a recognizable X-Stat field name (such as rails_env, custom_hooks_dir, or repo_pre_receive_hooks) is a strong indicator of an exploitation attempt.
Network-level indicators are not available because the exploit uses a standard SSH git push connection that is indistinguishable from legitimate traffic at the transport layer.
Attribution
No malicious threat actor is attributed to this vulnerability. It was discovered and responsibly disclosed by Wiz Research, with primary credit to Sagi Tzadik (@sagitz_), supported by Nir Ohfeld, Ronen Shustin, Hillai Ben-Sasson, Yuval Avrahami, and Noam Malron. The disclosure was made through GitHub's Bug Bounty program. GitHub CISO Alexis Wales confirmed the finding earned one of the highest rewards in the program's history. CISA's ADP Vulnrichment assessed the vulnerability as having no known exploitation at the time of CVE publication.
Primary Sources
- 01.GitHub RCE Vulnerability: CVE-2026-3854 Breakdown
Wiz Research Β· April 28, 2026
- 02.Securing the git push pipeline: Responding to a critical remote code execution vulnerability
GitHub Security Blog Β· April 28, 2026
- 03.CVE-2026-3854 Detail
NVD / NIST via OpenCVE Β· March 10, 2026
- 04.GitHub Enterprise Server Release Notes (CVE-2026-3854 entries)
GitHub Docs Β· March 10, 2026
- 05.A Single Git Push Was All It Took to Compromise GitHub: Millions of Repos Were Exposed
Cyber Kendra Β· April 28, 2026
- 06.Critical GitHub.com and Enterprise Server RCE Vulnerability Enables Full Server Compromise
Cybersecurity News Β· April 28, 2026