CVE-2026-109618 y CVE-2026-109619 aparecieron en php.net el 21 de octubre de 2026. Los dos son críticos, los dos están en el propio runtime y los dos permiten a un atacante ejecutar código en tu servidor sin iniciar sesión antes. Lo primero que pensé no tuvo nada que ver con el tipo de fallo. Me imaginé todos los hilos de Slack que empezaron a las 9:14 de esa mañana con un "pregunta rápida, ¿qué PHP tenemos en producción?" y que se quedaron sin respuesta mientras alguien buscaba la clave SSH correcta.

Así que esta es mi postura. Si para saber qué versión de PHP atiende tus peticiones en vivo hacen falta una persona, una terminal y una suposición, tienes un problema de inventario, y el próximo aviso sobre el runtime te lo va a destapar estés preparado o no. Cada despliegue debería registrar esa versión como un dato, justo al lado del hash del commit y del lock de Composer. Nunca debería ser algo que "se sabe" en el equipo.

Lo de la suposición importa más de lo que la mayoría reconocemos. En un servidor típico he visto cómo `php -v` muestra una versión menor mientras el pool de FPM que hay detrás de nginx ejecuta tan tranquilo otra distinta, porque un paquete de la distro, un PPA y una imagen base de Docker tenían cada uno su propia opinión al respecto. La CLI es la que aparezca primero en el PATH. Tus visitantes llegan a la que indique la configuración del pool. Si en la misma máquina corren un cron, un worker de colas y una petición web, eso puede significar tres intérpretes diferentes, y quizá solo uno de ellos haya recibido el parche.

La solución que me gustaría ver en todos los proyectos es aburrida a propósito. En tiempo de build, escribe `PHP_VERSION` y `PHP_SAPI` en un pequeño artefacto. En tiempo de ejecución, haz que cada SAPI que uses informe de esos mismos valores a un health check interno, y lanza una alerta cuando no coincidan o caigan por debajo de un mínimo que fijes en la configuración. Con eso, el día del aviso se convierte en una consulta al dashboard. Tienes la lista de máquinas que necesitan atención en unos cuatro minutos, cuando antes te esperaba una tarde de arqueología.

El mejor argumento en contra merece una respuesta directa: publicar la versión exacta de tu runtime es regalarle a un atacante el reconocimiento envuelto para regalo. Precisamente para eso existe `expose_php`, y por eso la gente sensata lo desactiva. Estoy totalmente de acuerdo. Nada de lo que describo debería aparecer en una cabecera pública ni en una ruta sin autenticación. Los datos van a tu stack de métricas o a un endpoint protegido con token al que solo llega tu monitorización. De todas formas, un atacante puede identificar tu stack con o sin tu ayuda. Quien no puede eres tú, un martes, con un CVE abierto en otra pestaña.

Hay una segunda objeción: en las plataformas gestionadas el runtime no es cosa tuya. Vale, puede que parchearlo no sea tu trabajo, pero conocer el riesgo sigue siendo responsabilidad tuya. Si tu proveedor de verdad mantiene PHP al día, tu health check lo confirmará y no te cuesta nada. Si no lo hace, te enteras por tu propia telemetría y no por el informe de incidentes de otro. Sinceramente, este es uno de los pocos puntos en los que la gente de Go lo tiene algo más fácil, porque el runtime va integrado en el binario que distribuyen. Nosotros podemos cambiar el intérprete por debajo del código en ejecución, lo cual es una ventaja real, siempre que sepamos qué intérprete hay ahí dentro.

PHP tiene un calendario de versiones y de seguridad predecible, y es una de las fortalezas discretas del ecosistema. El eslabón débil es la distancia entre un tarball corregido en php.net y el proceso que de verdad responde en el puerto 443. Así que cuéntame cómo cierras tú esa distancia. ¿Tu equipo registra hoy de forma automática la versión de PHP que sirve en cada máquina? Y si es así, ¿dónde vive ese número: en tu log de despliegues, en tu APM o todavía en la cabeza de alguien?