El 28 de marzo de 2021 aparecieron dos commits en la rama master de php-src en git.php.net, enviados bajo los nombres de Rasmus Lerdorf, creador de PHP, y del desarrollador principal Nikita Popov. Llevaban el título «[skip-ci] Fix typo»: un asunto lo bastante menor como para saltarse la revisión y, con el prefijo skip-ci, diseñado además para eludir la integración continua. El cambio, en una cabecera incluida de forma muy extendida, comprobaba una variable del servidor en busca del User-Agent HTTP y, si este comenzaba con la cadena «zerodium», ejecutaba el resto de la cabecera como código PHP: ejecución remota de código en cualquier servidor que ejecutara el intérprete envenenado.

No funcionó, y el motivo es aleccionador: los commits fueron detectados en cuestión de horas por miembros de la comunidad que leían el feed público —un comentarista señaló el cambio en el propio commit, y el desarrollador de PHP Jake Birchall confirmó que ejecutaba código procedente de la cabecera user-agent—. Popov anunció esa misma noche que todo apuntaba a un compromiso del servidor git.php.net y no de ninguna cuenta individual. El propio texto del commit incluía la línea «REMOVETHIS: sold to zerodium, mid 2017», lo que implica que la puerta trasera había sido vendida a un proveedor de exploits años antes.

La respuesta del proyecto fue eliminar el activo en lugar de repararlo. git.php.net se descontinuó en el acto; los espejos en GitHub, hasta entonces secundarios, pasaron a ser los repositorios canónicos; el acceso de escritura se trasladó a la organización php de GitHub con autenticación de dos factores obligatoria para ser miembro; y todas las versiones de PHP se pusieron en pausa durante dos semanas mientras se auditaban los repositorios en busca de más corrupción. Los dos commits nunca llegaron a un solo usuario final.

Ningún impacto en los usuarios finales: ambos commits se revirtieron antes de cualquier versión. El coste real fue la propia infraestructura git del proyecto y una congelación de dos semanas de todas las versiones de PHP

El proyecto gestionaba su propio servidor git con un sistema de karma casero para el acceso de escritura: una superficie de autenticación a medida que el pequeño equipo central tenía que defender por completo por su cuenta.

La identidad de los commits en ese servidor se basaba en la firma en el momento del push, no en firmas criptográficas, de modo que cualquiera que controlara el servidor podía hacer commits con los nombres más confiables del proyecto.

El disfraz estaba ajustado al proceso de revisión: una corrección de «typo» de una sola palabra, en una cabecera incluida en casi todas partes, con prefijo para saltarse por completo la CI.

Los espejos en GitHub que salvaron el proyecto habían pasado años como copias de segunda categoría; solo fueron recuperables porque el equipo decidió promoverlos en condiciones de emergencia.

Autoalojar el control de versiones no aporta nada a un proyecto salvo una superficie de ataque que debe defender en solitario. Los espejos solo compensan si están listos para convertirse en la fuente de verdad en la misma hora en que se los necesita.

php.net puso formalmente las versiones en pausa durante dos semanas mientras se realizaba la investigación, y declaró que los commits maliciosos fueron «detectados y revertidos de inmediato, y por tanto nunca llegaron a los usuarios finales». Se revisaron los repositorios en busca de corrupción más allá de los dos commits, GitHub se convirtió en el hogar canónico permanente de php-src, y la pertenencia a la organización ahora exige 2FA. El comentario del código de la puerta trasera —«sold to zerodium, mid 2017»— sigue siendo público en el historial de commits; el proveedor nunca confirmó haberla comprado.

CONSULTA LAS PRUEBAS

Las fuentes

  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 ·