Operación PHP2Shell

El 21 de Octubre de 2026, el ecosistema de PHP experimentó un evento de seguridad crítico de impacto global debido al descubrimiento de dos vulnerabilidades que permitían ejecutar código remoto, conocidas como PHP2Shell (CVE-2026-109618, CVE-2026-109619)

Recién me voy recuperando de una de las jornadas sin sueño más cabronas que he tenido, y quiero registrar el timeline de cómo lo viví, decisiones y aprendizajes de éste evento

3am - Señal de alerta

Me enteré de la vulnerabilidad por ahí de las 3am del 21 de Octubre, me topé un twit de The PHP Foundation y un par de comentarios mencionaban que se podía ejecutar código remoto con una simple llamada HTTP al servidor, no login, no acceso SSH, una vulnerabilidad crítica masiva que potencialmente afectariá 70% de internet

Me quitó el sueño, seguí leyendo posts de especialistas en seguridad, gente importante de PHP, varios compartieron recomendaciones para mitigar el riesgo, cada vez más de ellos mencionaban que no había manera real de mitigarlo hasta el parche

Mientras tanto, hackers en todo el mundo se habían enterado y estaban empezando a explotar la vulnerabilidad...

4am - Decisiónes

Para este punto, llevaba una hora pensando en cómo proteger nuestro sistema. La solución que mencionaban todos era esperar. Para mi esa no parecía una solución realmente, así que tomé la decision de directamente poner offline producción. Habilité el modo mantenimiento, se bloqueó todo trafico a nivel red y por 9 horas todos nuestros usuarios perdieron acceso al sistema

Nunca había tomado una decisión como ésta sin autorización... confié en mi instinto, horas después, aparecieron los twits de de la primera ministra de Japón y el departamento de Ciberseguridad de la Agencia de Seguridad Nacional de Estados Unidos

8am - La llegada del parche no fue suficiente

El parche oficialmente llegó y en cuanto me enteré, preparé el deploy con la configuración necesaria para actualizar la versión de PHP de producción

Las versiones que recibieron el parche fueron

  • 8.5.12
  • 8.4.27
  • 8.3.36
  • 8.2.35 

Y nuestra app estaba utilizando la versión 8.3.30, por lo que la solución era tan simple como actualizarla a 8.3.36, no breaking changes

El problema fue enterarme que nuestro entorno de producción no tendría acceso al parche... Por límites de nuestro proveedor, la versión máxima disponible para nuestro flujo de despliegue era la 8.3.30 y no iba a ser actualizada... en absoluto, sin fecha estimada de llegada

Cuando me enteré que tenía que cambiar el flujo de despliegue para cubrir el parche de seguridad empezó el verdadero reto

9am - Arquitecturas resilientes

Afortunadamente, decisiones técnicas que en algún momento se pueden sentir sobre-pensadas un día dan rendimientos

Cuando llegué a la empresa, todo el sistema vivía en un monolito: Un VPS barebones que gestionaban todo el proyecto: migraciones, archivos, datos, cron jobs. El equipo utilizaba un script para hacer deploy desde una maquina local, se conectaba vía SSH al servidor de prod y sobreescribía los archivos del proyecto. Ésta arquitectura no es mala per sé, funciona, pero es muy peligrosa, un solo punto de fallo afecta al sistema completo

En 2024, después de una crisis de seguridad importante que tuvimos, presenté mi propuesta arquitectónica y entre varias otras mejoras de seguridad, migramos a un modelo desacoplado, separando las responsabilidades de infraestructura en 4 capas:

  • Código
  • Cómputo
  • Archivos
  • Datos

Cada capa con su propio esquema de mantenimiento y controles de seguridad

Para el caso de Cómputo, en la empresa empezamos a utilizar App Platform (Digital Ocean) para desplegar el código dockerizado, independiente de las demás capas. Equivalente a (y compatible con) Heroku, App Platform utiliza Cloud Native Buildpacks para asumir las tecnologías necesarias para ejecutar el código; El builder lee los archivos del repositorio y construye una imagen de Docker haciendo un guess de las dependencias de nivel OS necesarias y las instala. Es una solución zero config que en la gran mayoría de casos acierta, y para algunos casos más complejos como el nuestro, lee un archivo project.toml para determinar los buildpacks específicos necesarios

Fast-forward a Octubre 2026

El parche de seguridad para PHP se publicó. Heroku actualizó inmediatamente su Buildpack de PHP a la versión 299 que ya incluye el parche, pero Digital Ocean no actualizó la suya, a la fecha sigue utilizando la versión 281 del Buildpack y no se ha pronunciado al respecto

Yo no sabía cómo la estaba pasando el resto del mundo, para mi ya había pasado una hora desde la salida del parche y nuestra app de producción seguía offline

Mi primer instinto fue usar directamente la tecnología de Cloud Native Buildpacks para construir la imagen nosotros y cambiar la configuración de App Platform para usarla, es decir, hacer nosotros el buildstep

Trabajar exclusivamente sobre la capa de Cómputo sin afectar las demás

10am - Rework de la capa de Cómputo

Instalé pack y mis pruebas locales resultaron bien. Ya estaba, lo único que restaba era cargar la imagen a un registry y configurar App Platform para usarla

Pronto actualizaré esta sección con los detalles de cómo lo resolví

1pm - Deploy exitoso

Después de revisar que staging estaba funcionando correctamente, decidí levantar prod. Redirigí el trafico al nuevo ambiente y avisé a mi equipo

Después hubo silencio, por horas no recibí ningún mensaje. Pero en lugar de preocuparme eso me alivió, mi dicho es que si no hay feedback, no hay problema. Si los usuarios no están quejándose significa que todo está en orden. Aún así, tocó esperar

Después de monitorear que los usuarios estuvieron utilizando la app con normalidad por un par de horas, mi sistema biológico de alerta se apagó, y mi cuerpo recordó que llevaba 30 horas sin dormir

En cuanto me recosté en la cama, morí

11pm - Misión cumplida

Después de dormir todo el día, una sensación de preocupación me despertó de golpe, pero cuando vi que no había notificaciones del trabajo lo supe, la operación había sido un éxito

Nuestro producto se mantuvo seguro gracias a decisiones acertadas de arquitectura, un interés genuino por las tecnologías que utilizamos y la habilidad de responder rápido a la vulnerabilidad

Hasta ahora sigo leyendo historias de terror de cómo ésta vulnerabilidad sigue afectando a miles de servidores, especialmente sistemas legacy que dependen de versiones antiguas de PHP seguirán apagando fuegos durante las próximas semanas