- Allein durch einen internen Protokollfehler im
git push-Pfad war Remotecodeausführung im Backend möglich; GitHub.com wurde bereits entschärft, GHES benötigt jedoch einen Patch - Die benutzergesteuerte Eingabe push option wurde unverändert in den Header
X-Statübernommen, sodass sich mit einem einzigen Semikolon neue Felder einschleusen ließen; ausgenutzt wurde dabei das last-write-wins-Verhalten, bei dem ein späterer Wert mit demselben Schlüssel einen früheren überschreibt - Durch die Kombination der einschleusbaren Felder
rails_env,custom_hooks_dirundrepo_pre_receive_hooksließ sich die Sandbox umgehen und ein Hook an einem vom Angreifer festgelegten Pfad mit den Rechten des Benutzersgitausführen - Über denselben Mechanismus ließ sich sogar das enterprise mode-Flag auf GitHub.com einschleusen, wodurch Codeausführung auf einem Shared-Storage-Node bestätigt wurde; dadurch konnten auch Repositories anderer Benutzer und Organisationen auf diesem Node gelesen werden
- Der Fall zeigt, wie in einer Multiservice-Architektur, in der verschiedene Dienste einem gemeinsamen Format vertrauen, fehlende Eingabebereinigung, nicht für Produktion gedachte Ausführungspfade und fehlende Pfadvalidierung zusammen eine schwerwiegende Schwachstelle erzeugen können
Sofortmaßnahmen und betroffener Umfang
- Bei GitHub.com ist das Problem bereits entschärft; es sind keine weiteren Maßnahmen erforderlich
- GitHub Enterprise Server erfordert sofortiges Handeln; ein Upgrade auf GHES 3.19.3 oder neuer mit dem Fix für
CVE-2026-3854ist notwendig - Der anfällige Versionsbereich ist GHES 3.19.1 und älter; als korrigierte Versionen werden
3.14.24,3.15.19,3.16.15,3.17.12,3.18.6,3.19.3genannt - Zum Zeitpunkt der Veröffentlichung waren 88 % der GHES-Instanzen noch verwundbar
- Weitere technische Details und Wiederherstellungsmaßnahmen von GitHub finden sich im GitHub Security Blog
- Wiz-Kunden können anfällige GHES-Instanzen mit der vorgefertigten Abfrage im Wiz Threat Center identifizieren
Hintergrund der Untersuchung und Vorgehensweise
- Die interne Git-Infrastruktur von GitHub verarbeitet alle
git push-Vorgänge über einen Pfad, in dem mehrere interne Dienste in unterschiedlichen Programmiersprachen geschrieben sind - In einer solchen Multiservice-Struktur können Unterschiede darin, wie einzelne Komponenten gemeinsam genutzte Daten parsen und ihnen vertrauen, zu Schwachstellen führen
- Bisher war das Extrahieren und Prüfen der vielen kompilierten Blackbox-Binärdateien in dieser Pipeline mit übermäßig viel Zeitaufwand und Handarbeit verbunden
- Mit KI-gestützten Werkzeugen und automatisiertem Reverse Engineering auf Basis von
IDA MCPkonnten kompilierte Binärdateien schnell analysiert und interne Protokolle rekonstruiert werden - Dabei wurde systematisch nachverfolgt, an welchen Stellen benutzergesteuerte Eingaben das Serververhalten entlang der gesamten Pipeline beeinflussen, und ein grundlegender Fehler im gesamten Eingabefluss aufgedeckt
Interne Architektur und Vertrauensgrenzen
- Wenn
git pushper SSH eingeht, läuft die Anfrage nacheinander durchbabeld,gitauth,gitrpcdund den pre-receive hook babeldist der Einstiegspunkt für alle Git-Operationen, nimmt die SSH-Verbindung an und übergibt die Authentifizierung angitauthgitauthprüft Benutzeranmeldedaten und Push-Berechtigungen für das Repository und liefert Sicherheitsrichtlinien wie Dateigrößenlimits oder Regeln für Branch-Namen zurück- Auf Basis dieser Antwort baut
babeldden internen HeaderX-Statmit Sicherheitsmetadaten auf gitrpcdübernimmt den HeaderX-Stat, setzt damit die Umgebung nachgelagerter Prozesse und vertrautbabeldvollständig, ohne selbst eine Authentifizierung durchzuführen- Der pre-receive hook prüft vor Annahme eines Pushes Dateigrößenlimits, Regeln für Branch-Namen, LFS-Integrität und administratorseitig definierte Custom Hooks
- Das entscheidende Bindeglied war der X-Stat-Header, der durch
;getrenntekey=value-Paare enthält - Interne Dienste zerlegen
X-Statanhand von;und füllen damit eine Map; kommt derselbe Schlüssel zweimal vor, überschreibt nach der last-write-wins-Regel der spätere Wert den früheren babeldschreibt außerdem die mitgit push -oübergebenen push options als Felder wiepush_option_0,push_option_1undpush_option_countinX-Stat
Ursache der Schwachstelle: Einschleusen von X-Stat-Feldern
babeldbereinigte beim Kopieren von benutzergesteuerten push option-Werten in den HeaderX-Statkeine Semikolons- Da
;als Feldtrenner inX-Statdient, konnte bereits ein einziges Semikolon innerhalb einer Push-Option ein neues angreiferkontrolliertes Feld außerhalb des ursprünglichen Feldes erzeugen - Wenn etwa in
push_option_0der Eintraglarge_blob_rejection_enabled=bool:falseeingeschleust wurde, überschreibt dieser spätere Wert den zuvor gesetzten Wertbool:true - Dieses Verhalten wurde sowohl durch Binäranalyse als auch durch Paketmitschnitte auf realen GHES-Instanzen bestätigt
- Durch die Kombination aus Reverse Engineering und Wire-Level-Analyse wurden einschleusbare
X-Stat-Felder systematisch kartiert - Als sicherheitsrelevante Felder wurden insbesondere
rails_env,custom_hooks_dir,repo_pre_receive_hooks,large_blob_rejection_enabled,reject_sha_like_refsunduser_operator_modeidentifiziert - Besonders die drei Felder
rails_env,custom_hooks_dirundrepo_pre_receive_hookswaren der Schlüssel für die Remotecodeausführung
Der Pfad zu RCE auf GHES
- GHES unterstützt Custom pre-receive hooks, die vor der Annahme eines Pushes ausgeführt werden
- Im pre-receive-Binärprogramm gab es zwei Ausführungspfade, die allein vom Wert
rails_envausX-Statabhingen - Bei
productionwurden Hooks innerhalb einer Sandbox ausgeführt; bei jedem anderen Wert liefen sie direkt ohne Sandbox und ohne Isolierung mit den Rechten des Dienstbenutzersgit - Durch das Einschleusen eines nicht-produktiven Werts für
rails_envließ sich daher die Sandbox umgehen - Durch das anschließende Einschleusen von
custom_hooks_dirkonnte der Angreifer das Basisverzeichnis kontrollieren, in dem nach Hook-Skripten gesucht wird - Wurde schließlich in
repo_pre_receive_hookseine Hook-Definition mit Path Traversal eingeschleust, kombinierte die Pfadauflösung der Binärdatei das angreiferkontrollierte Verzeichnis mit der Traversal-Nutzlast und zeigte dadurch auf einen beliebigen Pfad im Dateisystem - Der nicht-produktive Ausführungspfad führte den so aufgelösten Pfad dann ohne Argumente, ohne Sandbox und als Dienstbenutzer
gitdirekt aus - In der praktischen Verifikation lieferte ein einziger
git pushdie Ausgabeuid=500(git)zurück; damit war RCE mit den Rechten des Benutzersgitbestätigt - Mit diesen Rechten ließ sich vollständige Kontrolle über die GHES-Instanz erlangen, einschließlich Lese- und Schreibzugriffen auf das Dateisystem und Einblicken in interne Dienstkonfigurationen
Ausweitung auf GitHub.com und mandantenübergreifende Offenlegung
- Als dieselbe Exploit-Kette auf ein Repository auf GitHub.com angewendet wurde, war der Push zunächst erfolgreich, Custom Hooks wurden jedoch nicht ausgeführt
- Durch das Einschleusen von
user_operator_mode=bool:trueund den Vergleich der Debug-Ausgaben beider Plattformen zeigte sich, dass GitHub.com den Codepfad für Custom Hooks nicht erreichte - Weiteres Reverse Engineering ergab, dass im Header
X-Statein boolesches Flag vorhanden ist, das das Verhalten des enterprise mode auf dem Server steuert - Auf GHES ist dieses Flag standardmäßig true, sodass der Pfad für Custom Hooks immer aktiv ist; auf GitHub.com ist der Standardwert false, wodurch dieser Pfad im Normalzustand nicht erreicht wird
- Da sich auch dieses Flag über denselben Mechanismus einschleusen ließ, funktionierte nach dem Einschleusen eines weiteren Feldes die vollständige Exploit-Kette auch auf GitHub.com
- Danach wurde innerhalb der GitHub.com-Infrastruktur die Ausgabe von
hostnamezurückgeliefert; damit war RCE auf GitHub.com bestätigt - GitHub.com ist eine mandantenfähige Plattform, auf der Repositories vieler Benutzer und Organisationen in einer gemeinsam genutzten Backend-Infrastruktur gespeichert werden
- Die Codeausführung fand auf einem Shared-Storage-Node statt, auf dem der Benutzer
gitweitreichende Dateisystemrechte besitzt, um alle Repository-Operationen auf diesem Node zu verarbeiten - Wird dieser Benutzer kompromittiert, können auch die Repositories anderer Organisationen und Benutzer auf diesem Node unabhängig von deren Eigentümer gelesen werden
- Bei der Auflistung der auf zwei kompromittierten Nodes erreichbaren Repository-Indexeinträge fanden sich pro Node mehrere Millionen Einträge, darunter Repositories anderer Benutzer und Organisationen
- Auf die tatsächlichen Inhalte fremder Mandanten-Repositories wurde nicht zugegriffen; stattdessen wurde nur mit eigenen Testkonten verifiziert, dass die Dateisystemrechte des Benutzers
gitLesezugriff auf alle Repositories des Nodes erlauben
Zentrale Lehren und Zeitplan der Offenlegung
- Schon ein einzelner
git pushreichte aus, um über einen Fehler im internen Protokoll Remotecodeausführung in der Backend-Infrastruktur zu erreichen - Wenn mehrere in unterschiedlichen Sprachen geschriebene Dienste Daten über ein gemeinsames internes Protokoll austauschen, werden die Vertrauensannahmen jedes einzelnen Dienstes selbst zur Angriffsfläche
- In dieser Kette fügte ein Dienst Push-Option-Werte unverändert ein, ein anderer vertraute allen Feldern in
X-Stat, und der pre-receive hook ging in der Produktionsumgebung davon aus, dassrails_envaufproductiongesetzt sei - Nicht für Produktion gedachte Codepfade in Produktionsbinärdateien, fehlende Validierung von Path Traversal in Hook-Skripten und fehlende Eingabebereinigung in einem delimiterbasierten Protokoll sind Muster, die auch in anderen Codebasen auftreten können
- Teams, die Multiservice-Architekturen betreiben, sollten insbesondere dann prüfen, wie benutzergesteuerte Eingaben durch interne Protokolle fließen, wenn sicherheitskritische Einstellungen aus gemeinsam genutzten Datenformaten abgeleitet werden
- In dieser Untersuchung ermöglichten KI-gestützte Reverse-Engineering-Werkzeuge einschließlich
IDA MCPeine schnelle Analyse kompilierter Binärdateien und die Rekonstruktion interner Protokolle - Mit zunehmender Reife solcher Werkzeuge dürften sie eine immer wichtigere Rolle beim Auffinden von Schwachstellen spielen, die eine tiefe komponentenübergreifende Analyse erfordern
- Laut Offenlegungszeitplan wurde die X-Stat-Push-Option-Injection-Schwachstelle am
2026-03-04entdeckt; noch am selben Tag wurde RCE aufGHES 3.19.1bestätigt, an GitHub gemeldet und der Fix für GitHub.com ausgerollt - Am
2026-03-10wurden CVE-2026-3854 undCVSS 8.7vergeben, und der GHES-Patch wurde veröffentlicht - Am
2026-04-28erfolgte die Veröffentlichung
1 Kommentare
Hacker-News-Kommentare
Es ist im Grunde so, als hätte man in sicherheitskritische Header, die ein internes Authentifizierungsservice setzt,
auch noch beliebige Zeichenketten aufgenommen, die Endnutzer per
git push -oeinschleusen könnenIm Nachhinein ist man immer schlauer, aber das ist trotzdem einfach absurd
Der Ansatz des AI-gestützten Reverse Engineerings zeigt sehr gut, worin die Stärke heutiger LLM-Agenten liegt
Modelle, die stark auf Code trainiert wurden, können das Verständnis komplexer Systeminterna enorm beschleunigen
Sicherheitsforschung besteht oft aus einer Überlappung von 1) dem Verstehen komplizierter interner Abläufe und 2) dem Auffinden von Schwachstellen darin,
und nicht selten wird die eigentliche Lücke überraschend offensichtlich, sobald die internen Mechanismen einmal offenliegen
CVE-2026-3854 war nicht sofort ein offensichtlicher Fall, selbst wenn man die Interna kannte,
aber wäre diese Command Injection an einer traditionelleren oder leichter zugänglichen Angriffsfläche exponiert gewesen, hätte man sie wohl sehr schnell gefunden
In letzter Zeit wirkt es aber etwas so, als sei diese Entwicklung ins Stocken geraten oder werde absichtlich ausgebremst, vielleicht um ein durch die Komplexität der C++-Syntax entstehendes Dev-/Vendor-Lock-in zu schützen
Das Ergebnis wirkt so gut, dass man fast denkt, dort arbeite jemand von Wiz
Selbst nach extremem Wachstum und massiver Funktionsausweitung scheint das Produkt noch ziemlich gut standzuhalten,
und das Security-Team findet wirklich oft interessante Dinge
osv-scannerundtrivy, um auf Criticals zu schauenund bleibt dann ausgerechnet bei eher verdächtigen Dingen wie DC-Abfragen per CLI oder Credential-Resets still, was schon frustrierend ist
Wenn
babeldPush-Anfragen weiterleitet, packt es die Push-Optionen in den X-Stat-Header der internen Anfrage,und dieser Wert ist eine beliebige Zeichenkette, die der Nutzer per
git push -osetzen kannDas Problem ist, dass der Wert einfach unverändert kopiert wurde, ohne Semikolons zu sanitizen,
und weil
;als Feldtrenner im X-Stat-Header dient, kann ein Angreifer aus dem ursprünglichen Feld ausbrechen und neue Felder einschleusenDas ist wirklich ein Fehler der allereinfachsten Sorte, so als hinge die Frucht so tief, dass sie schon im Boden steckt
Obwohl die Schwachstelle entdeckt wurde, bevor sie bereits ausgenutzt worden war,
frage ich mich, ob Formulierungen wie BREAKING, unauthorized access oder millions of repositories nicht unnötig Angst schüren
https://x.com/wiz_io/status/2049153209982140718
GitHub hatte einfach Glück, dass nicht ein staatlich unterstützter Akteur zuerst darauf gestoßen ist, sondern das Fuzzing von Wiz
Dass 88 % der GHES-Instanzen einen kritischen Sicherheitspatch von vor 7 Wochen noch immer nicht eingespielt haben, wirkt ziemlich ernst
https://docs.github.com/en/enterprise-server@3.19/admin/release-notes#3.19.3
Schon für ein einzelnes Patch-Level-Release braucht man mehrere Stunden Downtime,
und es gibt nicht einmal ein unterstütztes HA-Upgrade-Verfahren, sodass selbst gewissenhafte Kunden kaum direkt aktuell bleiben können
Wenn man sich beschwert, heißt es immer nur, man solle zu GitHub Enterprise Cloud wechseln,
aber ob heute noch viele Leute das ohne Zögern wählen würden, ist fraglich
Immerhin bleibt GHES bei den täglichen Ausfällen von github.com verschont
und planen Upgrades vermutlich für Termine mit möglichst geringen betrieblichen Auswirkungen
Bei einer öffentlichen Instanz sollte man allerdings sofort updaten
Aus den Informationen im Artikel und dem öffentlich verfügbaren GitHub-Enterprise-Code allein lässt sich die Reproduktion wahrscheinlich ohne große Mühe herleiten
oder man bleibt beim Plan und hofft, dass nichts passiert — meist wird Letzteres gewählt
wäre es nicht ungewöhnlich, wenn ein On-Prem-Produkt nur einmal pro Jahr aktualisiert wird
Bei Enterprise-Software mit großen Datenmengen reichte oft schon eine Kleinigkeit, damit eine Installation kaputtgeht und das Ops-Team zurückrollen muss
Frühere SharePoint-Upgrades fühlten sich fast wie Würfeln an
Auch das hier ist wieder ein großer Erfolg von Wiz,
und es fühlt sich wie ein Wendepunkt dafür an, wie sehr AI-Tools RE und das Finden von Angriffspfaden anschieben können
Es ist ein weiterer Datenpunkt dafür, dass Sicherheit am Ende nicht auf security through obscurity bauen sollte
Alle reden davon, GitHub zu ersetzen, aber dann bleibt immer die Frage, womit eigentlich
Wenn selbst bei einer Plattform wie GitHub jetzt RCE auftaucht, kann man nicht leicht behaupten, Alternativen seien automatisch besser
https://news.ycombinator.com/item?id=46961345
https://news.ycombinator.com/item?id=47712656
und GitHub nur als Mirror zu verwenden, solange man dort kostenloses CI bekommt
Secrets kann man dann einem separaten Secret-Hosting-Provider überlassen
Ich kann immer noch kaum glauben, wie reaktionsschnell Forgejo ist und wie träge GitHub geworden ist
Interne liegen auf einer privaten Forgejo-Instanz, öffentliche kommen auf GitHub und werden nach Forgejo gespiegelt
Es hat uns überrascht, wie nah Forgejo an einem Single-Binary-System ist und wie leicht es sich konfigurieren lässt,
und weil alle internen Dienste auf Forgejo zeigen, hätten wir wenig Reibung, falls wir GitHub verlassen müssten
Ein All-in-One-Docker-Image und ein paar GitLab Runner reichen für kleine bis mittlere Teams völlig aus,
und ohne echten Bedarf muss man sich die Komplexität der Kubernetes-Version nicht antun
Schon dass AI Schwachstellen im Source Code findet, war beeindruckend,
aber das jetzt sogar in binären Executables zu schaffen, ist wirklich erstaunlich
Das hat enormes Potenzial — im Guten wie im Schlechten
Und wieder einmal zeigt sich die Lektion, dass man Daten nicht als Befehle behandeln darf
Alle Nutzereingaben müssen sanitizt werden
Deshalb war es nie überraschend, dass sie bei Source-to-Source oder Text-to-Source stark sind,
und dass sie auch gut darin sind, asm-Varianten zu verstehen, ist vielleicht nicht einmal völlig verblüffend
Beeindruckend bleibt es trotzdem
Ich frage mich, ob sich überhaupt feststellen lässt, ob das tatsächlich ausgenutzt wurde
Anhand von HTTP-/Git-Protokoll-Logs ließe sich wahrscheinlich bis zu einem gewissen Grad erkennen, ob es Ausnutzung gab,
aber was genau dabei aufgerufen wurde und wer es war, könnte durchaus unprotokolliert geblieben sein
Wenn der Exploit eigenständig auf dem Git-Server laufen konnte, könnte er definitionsgemäß am Logging vorbeigekommen sein