2 Punkte von GN⁺ 2026-04-29 | 1 Kommentare | Auf WhatsApp teilen
  • 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_dir und repo_pre_receive_hooks ließ sich die Sandbox umgehen und ein Hook an einem vom Angreifer festgelegten Pfad mit den Rechten des Benutzers git ausfü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-3854 ist 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.3 genannt
  • 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 MCP konnten 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 push per SSH eingeht, läuft die Anfrage nacheinander durch babeld, gitauth, gitrpcd und den pre-receive hook
  • babeld ist der Einstiegspunkt für alle Git-Operationen, nimmt die SSH-Verbindung an und übergibt die Authentifizierung an gitauth
  • gitauth prü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 babeld den internen Header X-Stat mit Sicherheitsmetadaten auf
  • gitrpcd übernimmt den Header X-Stat, setzt damit die Umgebung nachgelagerter Prozesse und vertraut babeld vollstä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 ; getrennte key=value-Paare enthält
  • Interne Dienste zerlegen X-Stat anhand 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
  • babeld schreibt außerdem die mit git push -o übergebenen push options als Felder wie push_option_0, push_option_1 und push_option_count in X-Stat

Ursache der Schwachstelle: Einschleusen von X-Stat-Feldern

  • babeld bereinigte beim Kopieren von benutzergesteuerten push option-Werten in den Header X-Stat keine Semikolons
  • Da ; als Feldtrenner in X-Stat dient, 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_0 der Eintrag large_blob_rejection_enabled=bool:false eingeschleust wurde, überschreibt dieser spätere Wert den zuvor gesetzten Wert bool: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_refs und user_operator_mode identifiziert
  • Besonders die drei Felder rails_env, custom_hooks_dir und repo_pre_receive_hooks waren 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_env aus X-Stat abhingen
  • Bei production wurden Hooks innerhalb einer Sandbox ausgeführt; bei jedem anderen Wert liefen sie direkt ohne Sandbox und ohne Isolierung mit den Rechten des Dienstbenutzers git
  • Durch das Einschleusen eines nicht-produktiven Werts für rails_env ließ sich daher die Sandbox umgehen
  • Durch das anschließende Einschleusen von custom_hooks_dir konnte der Angreifer das Basisverzeichnis kontrollieren, in dem nach Hook-Skripten gesucht wird
  • Wurde schließlich in repo_pre_receive_hooks eine 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 git direkt aus
  • In der praktischen Verifikation lieferte ein einziger git push die Ausgabe uid=500(git) zurück; damit war RCE mit den Rechten des Benutzers git bestä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:true und 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-Stat ein 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 hostname zurü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 git weitreichende 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 git Lesezugriff auf alle Repositories des Nodes erlauben

Zentrale Lehren und Zeitplan der Offenlegung

  • Schon ein einzelner git push reichte 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, dass rails_env auf production gesetzt 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 MCP eine 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-04 entdeckt; noch am selben Tag wurde RCE auf GHES 3.19.1 bestätigt, an GitHub gemeldet und der Fix für GitHub.com ausgerollt
  • Am 2026-03-10 wurden CVE-2026-3854 und CVSS 8.7 vergeben, und der GHES-Patch wurde veröffentlicht
  • Am 2026-04-28 erfolgte die Veröffentlichung

1 Kommentare

 
GN⁺ 2026-04-29
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 -o einschleusen können
    Im 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

    • Ursprünglich gab es Anzeichen dafür, dass AI besonders stark bei C++-Reverse-Engineering oder beim massenhaften Portieren von C++ zu einfachem C ist
      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

    • Dort gibt es viele Leute aus Unit 8200
    • Es gibt einfach zu viel Rauschen, deshalb nutzen wir nur eine Custom-Pipeline mit osv-scanner und trivy, um auf Criticals zu schauen
    • Ich arbeite zwar nicht dort, aber wenn wir das bei uns einsetzen, schlägt es ständig bei völlig harmlosen Aktionen an
      und bleibt dann ausgerechnet bei eher verdächtigen Dingen wie DC-Abfragen per CLI oder Credential-Resets still, was schon frustrierend ist
  • Wenn babeld Push-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 -o setzen kann
    Das 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 einschleusen
    Das ist wirklich ein Fehler der allereinfachsten Sorte, so als hinge die Frucht so tief, dass sie schon im Boden steckt

    • Ach ja, Bobby Tables' Mutter war wirklich klug
  • 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

    • Unzutreffend sind diese Formulierungen allerdings auch nicht
      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

    • GHES ist de facto seit Jahren fast vernachlässigt
      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
    • Viele On-Prem-Kunden haben GHES hinter einem VPN stehen
      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
    • In Enterprise-Umgebungen kann man für ein Update außerhalb des regulären Zeitplans alles kaputtmachen und dann die Verantwortung tragen,
      oder man bleibt beim Plan und hofft, dass nichts passiert — meist wird Letzteres gewählt
    • In Umgebungen, in denen man github.com gerade deshalb nicht nutzen darf, weil man Sicherheit sehr ernst nimmt,
      wäre es nicht ungewöhnlich, wenn ein On-Prem-Produkt nur einmal pro Jahr aktualisiert wird
    • In großen Installationen ist entscheidend, wie fragil der Upgrade-Prozess ist
      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

    • Das kratzt auch an dem Argument, man solle den Source nicht veröffentlichen, damit AI weniger einbrechen kann
      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

    • Man könnte natürlich scherzen, dass Thomas Dohmke das mit einem neuen Projekt schon richten wird
      https://news.ycombinator.com/item?id=46961345
      https://news.ycombinator.com/item?id=47712656
    • Die realistischste Antwort scheint noch zu sein, selbstgehostetes Forgejo als originäre Forge zu nutzen
      und GitHub nur als Mirror zu verwenden, solange man dort kostenloses CI bekommt
      Secrets kann man dann einem separaten Secret-Hosting-Provider überlassen
    • Wir sind vor 6 Monaten von GitHub zu Forgejo self-hosted gewechselt, und es läuft hervorragend
      Ich kann immer noch kaum glauben, wie reaktionsschnell Forgejo ist und wie träge GitHub geworden ist
    • Wir trennen inzwischen klar zwischen internen Projekten und öffentlich sichtbaren Projekten
      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
    • Self-hosted GitLab hinter einem VPN ist ebenfalls völlig okay
      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

    • Transformer wurden ursprünglich für Übersetzungen entworfen
      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

    • Meiner Ansicht nach könnte diese Schwachstelle sogar von anonymen Nutzern ausgenutzt werden
      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