CyberBytes Daily

Trending cyberattacks, explained simply.

critical vulnerability

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.

RESEARCHER DISCOVERY PHASEπŸ”¬1Target: closed-source binariesbabeld is compiled, no source code availableπŸ€–2AI-augmented reverse engineeringIDA MCP reconstructs internal protocolsπŸ—ΊοΈ3Pipeline mappingAll user-input touchpoints identified🎯4Injection point foundX-Stat header: semicolons not strippedAnalysis that would have taken weeks manually was completed in a fraction of the time using AI-augmented tooling.

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.

THE INJECTION MECHANISMπŸ’»1Developer runs git push -oPush option string sent to GitHubπŸ”€2babeld receives the requestEmbeds push option into X-Stat header⚠️3No semicolon strippingAttacker-injected fields pass throughπŸ”„4Last-write-wins parsingInjected fields overwrite server valuesTRUST BOUNDARY: USER INPUT ENTERS INTERNAL PROTOCOLA single semicolon in a push option value was enough to cross the trust boundary between user input and internal security metadata.

Phase 3: Three-Field RCE Chain

Wiz researcher Sagi Tzadik chained three injected X-Stat fields to achieve full remote code execution:

  1. Override rails_env: Controls which environment GitHub's backend runs in. Overriding it to a non-production value bypassed the production security sandbox.
  2. 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.
  3. 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.

THREE-FIELD RCE CHAINπŸ—οΈ1Inject rails_env overrideEscape production security sandboxπŸ“2Redirect custom_hooks_dirPoint to attacker-controlled pathπŸ’‰3Path traversal via pre-receive hookForce execution of arbitrary binary⚑Code execution as git userFull access to shared storage nodeπŸ—„οΈMillions of repo indexes exposedAcross all orgs on the same nodeOne git push command. Three injected semicolon-delimited fields. Full server compromise.

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.

DISCLOSURE AND PATCH TIMELINEπŸ“‹1March 4: Wiz reports to GitHubGitHub patches GitHub.com in under 2 hoursπŸ”’2March 10: GHES patches releasedAll supported branches coveredπŸ”3Forensic investigation completeNo prior exploitation confirmed⏰4April 28: Public disclosure88% of GHES instances still unpatchedThe patch was available for 49 days before public disclosure. Most self-hosted instances had not applied it.

What Made This Possible

  1. 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.

  2. 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.

  3. 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:

  1. Inject rails_env=<non-production value> to escape the production application sandbox.
  2. Inject custom_hooks_dir=<attacker-controlled path> to redirect the hook script lookup location.
  3. Inject repo_pre_receive_hooks=<path traversal payload> to force execution of an arbitrary binary as the git service 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.

TECHNICAL EXPLOIT PATHπŸ“‘1SSH git push -o receivedbabeld accepts push option stringπŸ”“2Unsanitized embed into X-StatSemicolons not stripped; fields injectedπŸ”„3Last-write-wins overriderails_env, custom_hooks_dir overwrittenπŸ’₯4repo_pre_receive_hooks traversalArbitrary binary executed as git userπŸ—„οΈRCE as git service userAccess to all repos on shared nodeCWE-77: the semicolon delimiter in X-Stat was the special element that was never neutralized.

CVE and Advisories

  • CVE-2026-3854: CVSS 4.0 score 8.7 (HIGH); CVSS 3.1 score 8.8 (HIGH). Affects GitHub Enterprise Server 3.14.0 through 3.19.2. Fixed in 3.14.24, 3.15.19, 3.16.15, 3.17.12, 3.18.6, and 3.19.3. Note: 3.15.19 and 3.16.15 were 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 IDATT&CK nameHow it appeared
T1190Exploit Public-Facing ApplicationThe git push endpoint is a public-facing interface; the injection was delivered through a standard client operation requiring only push access.
T1059Command and Scripting InterpreterThe 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.
T1548Abuse Elevation Control MechanismOverriding rails_env bypassed the production application sandbox, escaping an intended privilege boundary without exploiting a separate privilege escalation vulnerability.
T1083File and Directory DiscoveryOn GitHub.com, code execution as the git service user provided access to repository index entries across all organizations on the shared storage node.
T1565Data ManipulationThe 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