PHP2Shell y el costo de no actualizar
El 21 de octubre PHP publicó una actualización crítica de seguridad. Si tu stack corre PHP, ya tendría que estar aplicada. Si no corre PHP, esto también es para vos.
Qué pasó
El 20 de octubre el proyecto PHP anunció una versión de seguridad para el día siguiente, y ese mismo día ya circulaban reportes públicos de que las fallas permitían ejecutar código a distancia. El 21 de octubre salieron PHP 8.5.12, 8.4.27, 8.3.36 y 8.2.35, que corrigen dos vulnerabilidades: CVE-2026-109618 y CVE-2026-109619, conocidas juntas como PHP2Shell. Las dos tienen un puntaje de 9,2 sobre 10 en CVSS 4.0.
Lo que las vuelve serias se entiende con el alcance:
- Afectan a todas las versiones de PHP desde la 5.4, que salió en marzo de 2012, hasta la 8.5.11. Catorce años de versiones.
- Permiten ejecutar código de forma remota y sin autenticación en cualquier instalación que sirva web: PHP-FPM, Apache con mod_php, php-cgi, FrankenPHP o LiteSpeed.
- El problema está en el intérprete, no en tu aplicación. Da igual el framework, el CMS o lo prolijo que sea tu código: según Rapid7, en algunas configuraciones el ataque funciona antes de que corra una sola línea de la aplicación.
- El 26 de octubre CISA las sumó a su catálogo de vulnerabilidades explotadas activamente (KEV) y les dio a las agencias federales de Estados Unidos hasta el 29 para corregirlas.
- Unit 42, el equipo de investigación de Palo Alto Networks, identificó más de 22,6 millones de instancias expuestas potencialmente vulnerables.
Un detalle que se pierde fácil: instalar la versión nueva no alcanza. Hay que reiniciar los procesos que sirven PHP (los workers de PHP-FPM, Apache, FrankenPHP o LiteSpeed) y verificar que lo que responde en producción sea efectivamente la versión corregida. Hasta que el proceso viejo no se reinicia, sigue corriendo el código viejo.
Y no terminó ahí. El 23 de octubre PHP publicó un aviso extra por un caso residual, CVE-2026-115560, que según el proyecto solo afecta a configuraciones poco comunes. Al 4 de noviembre sigue sin parche: el arreglo llega con la próxima versión regular, y mientras tanto hay una mitigación publicada (está en el aviso de CERT-EU).
Vos escribiste el 5%
Cuando un equipo piensa en seguridad, piensa en su código: la validación de un formulario, los permisos, la consulta que nadie revisó. Está bien que lo haga. Pero hacé la cuenta con tu propio proyecto. Abajo de lo que escribiste hay un framework, decenas o cientos de paquetes, un runtime, un servidor web y un sistema operativo. Lo tuyo es una parte chica de lo que corre en producción; digamos el 5%. El otro 95% lo importaste.
PHP2Shell lo muestra con una claridad incómoda: equipos con código impecable quedaron expuestos por una pieza que no escribieron, que no revisan y que, muchas veces, ni saben en qué versión está.
«Si funciona, no lo toques»
Es una de las frases más repetidas de la industria, y una de las más caras. Suena prudente, pero en la práctica es deuda, y la deuda técnica tiene interés compuesto.
Pasar de PHP 8.3 a 8.4 lleva una tarde. Pasar de 7.4 a 8.4 es un proyecto: cambios del lenguaje acumulados durante años, librerías que ya no soportan tu versión y otras que directamente dejaron de existir. Ese proyecto se puede planificar un martes cualquiera. El día que sale una vulnerabilidad crítica no tenés semanas para hacerlo: tenés horas. Y quien ese día está en 7.4 no tiene un parche para aplicar. Tiene una migración que fue postergando.
Un runtime sin soporte es un riesgo que aceptaste sin firmar nada
PHP 7.4 dejó de recibir parches de seguridad el 28 de noviembre de 2022; PHP 8.0, el 26 de noviembre de 2023; PHP 8.1, el 31 de diciembre de 2025. Para PHP2Shell, el proyecto hizo una excepción y publicó parches mínimos en código fuente para esas tres ramas, pensados para quien compila PHP por su cuenta. No hubo versiones nuevas. Si tu PHP viene de una distribución o un proveedor con soporte extendido, quizás te llegó el arreglo por ese lado. Pero fue una excepción, no una promesa: esas ramas no tienen por qué recibir el próximo. Con o sin parche, hay que migrar.
¿Cuánta gente está en esa situación? Según W3Techs, al 4 de noviembre PHP corre en el 69,1% de los sitios web cuyo lenguaje de servidor se conoce. De esos, el 26,2% sigue en PHP 7 y el 7,6% en PHP 5. O sea: más de un tercio de la web en PHP corre en versiones mayores que el proyecto ya no mantiene. Y PHP 8.2, que hoy todavía recibe parches, deja de recibirlos el 31 de diciembre de 2026.
No es un problema de PHP. Node.js 18 llegó al fin de su soporte el 30 de abril de 2025, y Node.js 20 el 30 de abril de 2026. Python 3.9, el 31 de octubre de 2025. Nadie firmó un papel aceptando correr software sin parches; simplemente pasó la fecha y nadie miró el calendario.
Automatizar el aviso no es automatizar la actualización
Dependabot y Renovate son buenas herramientas. Revisan tus dependencias, te avisan cuando hay una versión nueva o una vulnerabilidad conocida y te abren el pull request listo para revisar. El problema empieza cuando esos PRs se acumulan. Con cuarenta abiertos, nadie los mira, y el día que llega uno crítico queda enterrado entre actualizaciones menores de una librería de fechas. En ese punto la herramienta es decorativa: da la sensación de que alguien se está ocupando, y nadie se está ocupando.
No todo advisory es una emergencia (pero hay que mirar para saberlo)
La mayoría de los avisos de seguridad son de severidad baja, afectan funciones que no usás o están en dependencias de desarrollo que nunca llegan a producción. Tratarlos a todos como un incendio es la forma más rápida de que el equipo deje de leerlos. Pero para saber cuál es ruido y cuál no, alguien tiene que mirarlos. PHP2Shell era crítica, no pedía autenticación, estaba en el runtime y se estaba explotando. Eso no se agenda para el próximo sprint.
Tres cosas para hacer hoy
-
Corré el audit de tus dependencias. Casi todos los ecosistemas tienen uno: npm, Composer, pip, NuGet, Bundler, Cargo. En algunos viene incluido en el gestor de paquetes y en otros es una herramienta aparte. Casi todos tardan menos de un minuto:
npm audit # npm composer audit # Composer pip-audit # pip dotnet list package --vulnerable # NuGet bundle audit # Bundler cargo audit # Cargopip-audit,bundle audit(de la gema bundler-audit) ycargo auditse instalan aparte. Lo importante no es el número total, sino qué dice en las críticas y las altas. Ojo: el audit revisa los paquetes, no el runtime. Que salga limpio no te dice si tu versión de PHP, Node o Python sigue teniendo soporte; eso es el paso 2.Si querés una segunda mirada, pasale a una IA como Claude o ChatGPT la lista de dependencias con sus versiones (lo que dice tu
package.json,composer.json,requirements.txt,Gemfileo.csproj) y pedile que te marque qué está viejo o sin soporte. Solo la lista: sin credenciales, sin URLs privadas, sin nada interno. Sirve para ordenar y entender, pero después verificalo con el audit y con las fuentes oficiales, porque la IA puede no estar al día con lo que salió la semana pasada. - Mirá la versión de tu runtime y su fecha de fin de soporte. PHP, Node, Python, .NET, Java, lo que sea. endoflife.date tiene las fechas de casi todo en un solo lugar. Si ya pasó, tenés un proyecto pendiente. Si pasa en los próximos seis meses, también.
- Contá los PRs abiertos de Dependabot o Renovate. Si son más de tres, bloqueá dos horas esta semana para revisarlos. No hace falta mergear todo; hace falta saber qué hay.
Mantener las dependencias al día no tiene nada de glamoroso y nunca va a ser la feature que se muestra en la demo. Va a salir otra vulnerabilidad crítica en algo que importaste; eso no se discute. Lo que sí podés decidir es con cuánto atraso te va a encontrar ese día. Y si alguien pregunta «¿y esto cómo se paga?», la respuesta es simple: sale bastante más barato que la alternativa.
Fuentes
- Rapid7: CVE-2026-109618 y CVE-2026-109619 (alcance, versiones corregidas, ingreso al catálogo KEV)
- CISA: Critical Vulnerabilities in PHP Require Immediate Patching
- Google Cloud: Responding to core PHP vulnerabilities (versiones afectadas desde 5.4)
- Unit 42 (Palo Alto Networks) (instancias expuestas)
- CERT-EU, Security Advisory 2026-018 (cronología y CVE-2026-115560)
- CISA, catálogo KEV (cisagov/kev-data) (alta el 26 de octubre, vencimiento el 29)
- PHP: versiones con soporte y ramas sin soporte
- PHP: archivo de versiones (PHP 5.4, marzo de 2012)
- W3Techs: uso de PHP por versión (datos al 4 de noviembre de 2026)
- endoflife.date (fechas de fin de soporte de PHP, Node.js y Python)
Este artículo no incluye detalles técnicos de cómo se explotan las fallas, a propósito. Si necesitás mitigar, el lugar es el aviso oficial de PHP o el de CERT-EU.