Le 28 mars 2021, deux commits sont apparus dans la branche master de php-src sur git.php.net, poussés sous les noms de Rasmus Lerdorf, créateur de PHP, et du développeur principal Nikita Popov. Ils étaient intitulés « [skip-ci] Fix typo » — un intitulé assez anodin pour échapper à la relecture et, avec le préfixe skip-ci, conçu pour contourner aussi l'intégration continue. La modification, dans un en-tête inclus très largement, vérifiait une variable serveur pour l'HTTP User-Agent et, si celle-ci commençait par la chaîne « zerodium », exécutait le reste de l'en-tête comme du code PHP : exécution de code à distance sur tout serveur faisant tourner l'interpréteur empoisonné.

Cela n'a pas fonctionné, et la raison est instructive : les commits ont été repérés en quelques heures par des membres de la communauté lisant le flux public — un commentateur a signalé la modification sur le commit lui-même, et le développeur PHP Jake Birchall a confirmé qu'elle exécutait du code issu de l'en-tête user-agent. Popov a annoncé le même soir que tout indiquait une compromission du serveur git.php.net plutôt que d'un compte individuel. Le texte du commit portait lui-même la ligne « REMOVETHIS: sold to zerodium, mid 2017 », suggérant que la porte dérobée avait été négociée avec un vendeur d'exploits des années plus tôt.

La réponse du projet a été de supprimer l'actif plutôt que de le réparer. git.php.net a été abandonné sur-le-champ ; les miroirs GitHub, jusque-là secondaires, sont devenus les dépôts canoniques ; l'accès en écriture a été transféré à l'organisation php sur GitHub, l'authentification à deux facteurs étant exigée pour en être membre ; et toutes les versions de PHP ont été suspendues pendant deux semaines, le temps que les dépôts soient audités à la recherche d'autres corruptions. Les deux commits n'ont jamais atteint le moindre utilisateur final.

Aucun impact sur les utilisateurs finaux — les deux commits ont été annulés avant toute version. Le coût réel a été l'infrastructure git propre au projet et un gel de deux semaines de toutes les versions de PHP

Le projet exploitait son propre serveur git avec un système de karma maison pour l'accès en écriture — une surface d'authentification sur mesure que la petite équipe centrale devait défendre entièrement seule.

L'identité des commits sur ce serveur reposait sur une validation au moment du push, et non sur des signatures cryptographiques, de sorte que quiconque contrôlait le serveur pouvait committer sous les noms les plus dignes de confiance du projet.

Le déguisement était calibré sur le processus de relecture : une correction de « typo » d'un seul mot, dans un en-tête inclus presque partout, préfixée pour contourner entièrement l'intégration continue.

Les miroirs GitHub qui ont sauvé le projet avaient passé des années comme copies de seconde classe — récupérables uniquement parce que l'équipe a choisi de les promouvoir dans des conditions d'urgence.

Auto-héberger son contrôle de version n'apporte à un projet rien d'autre qu'une surface d'attaque qu'il doit défendre seul. Les miroirs ne valent que s'ils sont prêts à devenir la source de vérité à l'heure où vous en avez besoin.

php.net a formellement suspendu les versions pendant deux semaines le temps que l'enquête se déroule, déclarant que les commits malveillants avaient été « immédiatement remarqués et annulés, et n'ont donc jamais atteint les utilisateurs finaux ». Les dépôts ont été examinés à la recherche de corruptions au-delà des deux commits, GitHub est devenu le foyer canonique permanent de php-src, et l'adhésion à l'organisation exige désormais la 2FA. Le commentaire de code de la porte dérobée — « sold to zerodium, mid 2017 » — reste public dans l'historique des commits ; le vendeur n'a jamais confirmé l'avoir achetée.

VÉRIFIEZ LES SOURCES

Les sources

  1. Changes to Git commit workflow (php.internals #113838) news-web.php.net · news-web.php.net ·
  2. PHP releases on hold php.net · php.net ·
  3. [skip-ci] Fix typo (commit c730aa26) GitHub php/php-src · github.com ·
  4. PHP's Git server hacked to add backdoors to PHP source code BleepingComputer · bleepingcomputer.com ·