Am 28. März 2021 erschienen zwei Commits im Master-Branch von php-src auf git.php.net, gepusht unter den Namen von Rasmus Lerdorf, dem Erfinder von PHP, und dem Kernentwickler Nikita Popov. Sie trugen den Titel „[skip-ci] Fix typo“ – ein Gegenstand klein genug, um die Überprüfung zu überspringen, und mit dem skip-ci-Präfix zusätzlich darauf ausgelegt, die kontinuierliche Integration zu umgehen. Die Änderung in einem weithin eingebundenen Header prüfte eine Servervariable auf den HTTP User-Agent und führte, wenn dieser mit der Zeichenkette „zerodium“ begann, den Rest des Headers als PHP-Code aus: Remote-Code-Ausführung auf jedem Server, der den vergifteten Interpreter ausführte.
Sie funktionierte nicht, und der Grund ist lehrreich: Die Commits wurden innerhalb von Stunden von Community-Mitgliedern entdeckt, die den öffentlichen Feed lasen – ein Kommentator meldete die Änderung direkt am Commit, und der PHP-Entwickler Jake Birchall bestätigte, dass sie Code aus dem User-Agent-Header ausführte. Popov verkündete noch am selben Abend, alles deute auf eine Kompromittierung des Servers git.php.net hin und nicht auf ein einzelnes Konto. Der Commit-Text selbst enthielt die Zeile „REMOVETHIS: sold to zerodium, mid 2017“, was impliziert, dass die Hintertür Jahre zuvor an einen Exploit-Anbieter vermittelt worden war.
Die Reaktion des Projekts bestand darin, das Asset zu entfernen statt es zu reparieren. git.php.net wurde auf der Stelle eingestellt; die GitHub-Mirrors, bis dahin zweitrangig, wurden zu den kanonischen Repositories; der Schreibzugriff wanderte zur php-GitHub-Organisation, wobei für die Mitgliedschaft Zwei-Faktor-Authentifizierung erforderlich ist; und alle PHP-Releases wurden für zwei Wochen ausgesetzt, während die Repositories auf weitere Korruption geprüft wurden. Die beiden Commits erreichten nie einen einzigen Endnutzer.
Keine Auswirkungen auf Endnutzer – beide Commits wurden vor jedem Release zurückgenommen. Der eigentliche Preis war die eigene Git-Infrastruktur des Projekts und ein zweiwöchiger Stillstand aller PHP-Releases
Das Projekt betrieb einen eigenen Git-Server mit einem selbstgebauten Karma-System für den Schreibzugriff – eine maßgeschneiderte Authentifizierungsoberfläche, die das kleine Kernteam ganz allein verteidigen musste.
Die Commit-Identität auf diesem Server beruhte auf der Sign-off-Bestätigung zum Zeitpunkt des Push, nicht auf kryptografischen Signaturen, sodass jeder, der den Server kontrollierte, unter den vertrauenswürdigsten Namen des Projekts committen konnte.
Die Tarnung war auf den Überprüfungsprozess abgestimmt: eine Ein-Wort-„Typo“-Korrektur in einem fast überall eingebundenen Header, mit einem Präfix versehen, um die CI vollständig zu überspringen.
Die GitHub-Mirrors, die das Projekt retteten, waren jahrelang Kopien zweiter Klasse gewesen – wiederherstellbar nur, weil das Team sich entschied, sie unter Notfallbedingungen zu fördern.
Selbst gehostete Versionskontrolle bringt einem Projekt nichts außer einer Angriffsfläche, die es allein verteidigen muss. Mirrors zahlen sich nur aus, wenn sie bereit sind, in der Stunde, in der man sie braucht, zur Quelle der Wahrheit zu werden.
php.net setzte die Releases offiziell für zwei Wochen aus, während die Untersuchung lief, und erklärte, die bösartigen Commits seien „sofort bemerkt und zurückgenommen worden und hätten somit nie Endnutzer erreicht“. Die Repositories wurden auf Korruption über die beiden Commits hinaus geprüft, GitHub wurde zum dauerhaften kanonischen Zuhause von php-src, und für die Mitgliedschaft in der Organisation ist nun 2FA erforderlich. Der Code-Kommentar der Hintertür – „sold to zerodium, mid 2017“ – bleibt in der Commit-Historie öffentlich; der Anbieter bestätigte den Kauf nie.
DEN BELEGEN FOLGEN
Die Quellen
- Changes to Git commit workflow (php.internals #113838) news-web.php.net · news-web.php.net ·
- PHP releases on hold php.net · php.net ·
- [skip-ci] Fix typo (commit c730aa26) GitHub php/php-src · github.com ·
- PHP's Git server hacked to add backdoors to PHP source code BleepingComputer · bleepingcomputer.com ·