Situación revisada el 21 de octubre de 2026, con los parches ya publicados. Los datos sobre las vulnerabilidades proceden de las fuentes oficiales, enlazadas en cada apartado. Las pautas operativas son la propuesta de respuesta de ekko y conviene adaptarlas a cada servidor; no se han realizado pruebas de ataque ni auditorías de alojamientos de terceros.
¿Qué conviene hacer de inmediato si una web funciona con PHP?
Identificar el intérprete de cada dominio, instalar una versión corregida y reiniciar sus procesos. Mientras no sea posible parchear, conviene bloquear el acceso en el servidor web o en el proxy, de modo que las peticiones no lleguen a PHP.
- Abrir una incidencia con el alojamiento o con el administrador del servidor. En ella deben figurar los dos identificadores, CVE-2026-109618 y CVE-2026-109619, junto con la petición de que se confirme el paquete instalado y el reinicio de los procesos.
- Hacer inventario de todos los dominios. Subdominios, entornos de pruebas, tiendas, webmail, gestores de archivos y aplicaciones que nadie recuerda: cada uno puede funcionar con una versión distinta.
- Disponer de una copia de seguridad recuperable de los datos y de la configuración, guardada fuera del servidor. En una tienda online conviene elegir la ventana de mantenimiento de forma que no se pierdan pedidos.
- Aplicar el parche que corresponda a la rama y al proveedor, probar las funciones críticas y reiniciar los procesos que ejecutan PHP. En caso de que hoy no sea viable, pueden aplicarse las medidas urgentes del aviso oficial mientras tanto.
- Comprobar el resultado desde la propia web y conservar la evidencia de cada dominio. La salida de una consola, por sí sola, no basta.
El procedimiento cambia según el entorno, ya sea un hosting con panel, un VPS o una plataforma de contenedores, y más abajo se trata cada caso por separado.
¿Qué son CVE-2026-109618 y CVE-2026-109619?
Son dos vulnerabilidades críticas de PHP, publicadas el 21 de octubre de 2026, que permiten ejecutar código en el servidor sin autenticación. Esta es su ficha técnica.
| Dato | CVE-2026-109618 | CVE-2026-109619 |
|---|---|---|
| Aviso de GitHub | GHSA-w8hw-w9fx-j79w | GHSA-6wmf-4rv5-p3rp |
| Nombre oficial | RCE via OOM corruption | RCE via stale global state |
| Origen del fallo | Corrupción de memoria al agotarse memory_limit |
Estado global obsoleto entre peticiones (use-after-free) |
| Impacto | Ejecución remota de código sin autenticación | Ejecución remota de código sin autenticación y fuga de memoria |
| Gravedad | CVSS v4.0 9,2, crítica | CVSS v4.0 9,2, crítica |
| Explotación validada en | Apache con mod_php |
mod_php y PHP-FPM |
| Versiones vulnerables | Cualquiera anterior a 8.2.35, 8.3.36, 8.4.27 u 8.5.12 dentro de su rama | Las mismas |
| Corregido en | 8.5.12, 8.4.27, 8.3.36 y 8.2.35 | Las mismas |
| Medida parcial oficial | memory_limit=-1 impuesto, post_max_size bajo y límites de petición |
session.upload_progress.enabled=0 y, en 8.5, fatal_error_backtraces=0 |
Ambas comparten el vector CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N, lo que significa que se explotan por red, sin credenciales ni interacción del usuario, aunque con una complejidad alta. Las debilidades asociadas (CWE) son también las mismas: CWE-416, CWE-755, CWE-824, CWE-1325 y CWE-1419. La información procede del aviso de seguridad de php.net y de los dos avisos de GitHub citados en la tabla.
¿Qué ha ocurrido y qué versiones corrigen el problema?
PHP ha publicado correcciones para dos fallos de ejecución remota de código. El parche del intérprete es imprescindible aunque el CMS y sus extensiones estén al día.
El equipo de seguridad de PHP lanzó un preaviso el 20 de octubre. En él adelantaba la puntuación de ambos fallos, CVSS v4.0 de 9,2, y fijaba la publicación para el día 21 a las 14:00 UTC (las 16:00 en Madrid). Aquella hora era una previsión, y no garantizaba que cada proveedor de alojamiento tuviera el parche disponible en ese momento.
El aviso de seguridad del 21 de octubre confirmó las versiones corregidas y la posibilidad de ejecutar código a distancia sin autenticación. El registro oficial de cambios enlaza las dos correcciones:
| Rama | Primera versión corregida en esta incidencia |
|---|---|
| PHP 8.5 | 8.5.12 |
| PHP 8.4 | 8.4.27 |
| PHP 8.3 | 8.3.36 |
| PHP 8.2 | 8.2.35 |
Se trata de los mínimos para esta incidencia y no de una recomendación permanente. Quien consulte esta guía más adelante debería comprobar cuál es la última versión de seguridad disponible para su rama.
Según PHP, las distribuciones Linux y los proveedores con soporte extendido (LTS) recibieron los parches por adelantado. Si un proveedor todavía no ofrece el paquete corregido, es legítimo preguntarle por qué. Hay además una fecha que tener en cuenta: PHP 8.2 deja de recibir correcciones de seguridad el 31 de diciembre de 2026, de modo que quien parchee hoy una instalación 8.2 haría bien en planificar ya el cambio de rama.
En PHP 8.1 y versiones anteriores el proyecto ya no publica versiones ordinarias. Las opciones pasan por un backport acreditado del proveedor o por migrar a una rama con soporte. PHP ha puesto a disposición parches mínimos de código fuente para 7.4, 8.0 y 8.1, pensados para quien compila el intérprete por su cuenta o no cuenta con un proveedor LTS. Eso no equivale a recuperar el soporte, ni implica que el hosting vaya a actualizarse solo. El detalle figura en el aviso oficial.
En las distribuciones, lo que cuenta es la revisión completa del paquete. Ubuntu 24.04, por ejemplo, publica la corrección como 8.3.6-0ubuntu0.24.04.13, y Ubuntu 22.04 como 8.1.2-1ubuntu2.28. El número base parece anterior al mínimo oficial porque el paquete incorpora los parches retroportados. Los dos CVE aparecen en el boletín USN-8948-1. Estas cifras valen únicamente para los repositorios oficiales de Ubuntu; no sirven para un PPA, para otra distribución ni para los paquetes de un panel.
¿Cómo funcionan técnicamente estas dos vulnerabilidades?
Las dos afectan a la gestión de la memoria de PHP entre peticiones. En un caso quedan datos a medio inicializar; en el otro, una petición reutiliza referencias que ya se habían liberado.
CVE-2026-109618 (GHSA-w8hw-w9fx-j79w): RCE por corrupción en falta de memoria
Cuando se agota la memoria, PHP sale de la operación en curso con un salto longjmp(). Si eso ocurre en mitad de una inicialización, el proceso de limpieza posterior trabaja con un estado inválido. Los investigadores lograron una ejecución remota de código completa por HTTP contra mod_php, con los límites de memoria y de entrada que trae PHP por defecto, y antes de que llegara a ejecutarse código de la aplicación. El mecanismo se detalla en el aviso técnico de PHP.
El aviso explica también cómo puede una petición agotar la memoria sin rebasar en apariencia los límites de PHP, y de ahí se derivan buena parte de las medidas urgentes:
- Una petición multipart que carezca de un
Content-Lengthutilizable puede superar el control depost_max_sizey seguir enviando datos. - Cada parte de un envío multipart admite un número ilimitado de cabeceras, que dentro de PHP ocupan mucho más que en la red.
- Los campos de archivo vacíos no cuentan para
max_file_uploads, pero generan igualmente sus estructuras internas, y los nombres de campo anidados multiplican ese trabajo.
La corrección sustituye el longjmp() por un fallo de memoria diferido, que se gestiona en el siguiente punto seguro, y por una terminación inmediata cuando el consumo alcanza un segundo umbral, más alto.
CVE-2026-109619 (GHSA-6wmf-4rv5-p3rp): RCE por estado global obsoleto
En este caso, un proceso de PHP conserva referencias a la memoria de una petición ya liberada, y otra petición atendida por ese mismo proceso las utiliza antes de que se reinicialicen. Es lo que se conoce como use-after-free.
Para que el ataque prospere hacen falta dos piezas. La primera, que el aviso llama «productor», es una interrupción que deja el estado sin limpiar: un error fatal, un agotamiento de memoria o un tiempo de ejecución excedido. La segunda, el «consumidor», es una operación que lee ese estado antes de la inicialización normal. Hay dos consumidores confirmados, un aviso de configuración INI aplicado en cada petición y el progreso de subida de archivos de las sesiones. Los dos casos comprobados son los backtraces de errores fatales de PHP 8.5, con explotación demostrada en mod_php, y el ciclo de vida de las sesiones, validado tanto en mod_php como en PHP-FPM; en este último hace falta además una operación adecuada de la aplicación. Los detalles están en el segundo aviso técnico.
Impacto confirmado
Quien explote cualquiera de los dos fallos obtiene ejecución de código con los permisos de la cuenta del servidor web, sin necesidad de autenticarse; el segundo permite también leer memoria. A efectos prácticos, todo lo que esa cuenta pueda leer queda expuesto, desde wp-config.php hasta las credenciales de la base de datos.
La puntuación CVSS refleja una complejidad de ataque alta. Disponer de muchos procesos y de tráfico legítimo reduce la probabilidad de éxito en cada intento, pero, según PHP, no elimina la condición.
De ello se desprende algo relevante para el diagnóstico. Que la aplicación valide bien sus formularios no dice nada sobre la seguridad del intérprete, y que la portada cargue con normalidad tampoco.
¿Afecta a WordPress, PrestaShop, Laravel o solo a Apache?
Lo que hay que revisar es el PHP que ejecuta cada aplicación. Cambiar de CMS o tener los plugins al día no acredita que el intérprete esté corregido.
El aviso de PHP incluye cualquier instalación que atienda peticiones web, tanto con PHP-FPM como con Apache y mod_php, php-cgi, FrankenPHP o LiteSpeed. Entre unas y otras cambia el grado de prueba disponible, pero la necesidad de parchear es la misma para todas:
| Forma de ejecutar PHP | Lo que indican los avisos | Prioridad (criterio de ekko) |
|---|---|---|
Apache con mod_php |
Explotación completa validada en los dos CVE; en el primero, sin depender de la aplicación | Primera |
| FrankenPHP | En el primer CVE, el análisis del código apunta a que es vulnerable sin depender de la aplicación | Justo después |
| PHP-FPM | Susceptible al primero, sin un exploit completo demostrado; explotación validada del segundo a través de las sesiones | Alta |
| LiteSpeed (LSAPI) | Se comporta como FPM; se consideran probables los ataques dependientes de la aplicación, aunque no se han validado | Alta |
| php-cgi | Incluido en el aviso general; los avisos técnicos no detallan su caso | Alta |
Si no se sabe cuál de ellos utiliza el hosting, conviene preguntarlo. Muchos alojamientos compartidos funcionan con LiteSpeed o con mod_php y no con FPM.
El criterio que propone ekko es considerar pendiente de intervención cualquier aplicación PHP accesible desde internet mientras no se haya acreditado su corrección. Cuando la aplicación la gestione un tercero, procede pedirle la evidencia. Y en una web exportada a HTML, la revisión debería alcanzar también al panel de edición y a cualquier servicio auxiliar que siga ejecutándose.
Nada de lo anterior significa que todos los sitios sean explotables del mismo modo, ni que hayan sufrido una intrusión. Que exista una demostración de ataque no prueba que haya una campaña activa contra una web concreta, y los avisos publicados tampoco permiten certificar lo contrario.
¿Qué puede hacerse si solo se dispone del panel del hosting?
Solicitar al proveedor el parche de ambos CVE y el reinicio de los procesos. Elegir «PHP 8.3» en el selector del panel no indica qué revisión ejecuta realmente la web.
El panel sirve para anotar qué versión tiene asignada cada dominio. Si ofrece una revisión corregida y compatible, basta con seleccionarla y probar el sitio. Si solo muestra la rama, habrá que pedir el número completo o la referencia del parche aplicado por el proveedor.
Este mensaje puede enviarse tal cual al soporte técnico:
Necesito confirmar la corrección de CVE-2026-109618 y CVE-2026-109619 en los dominios de mi cuenta. Indicad versión y revisión del paquete PHP de cada dominio, cómo se ejecuta (mod_php, PHP-FPM, LiteSpeed u otro), referencia del parche si es un backport y confirmación de renovación de todos los procesos que lo ejecutan. Si sigue pendiente, indicad plazo, si habéis aplicado las medidas temporales del aviso de PHP (session.upload_progress.enabled=0, memory_limit y límites de tamaño de petición) y cómo bloquear el acceso en el servidor web para que las peticiones no lleguen a PHP.
Se trata de una plantilla; ekko no la ha enviado a ningún proveedor.
Una respuesta del tipo «WordPress está actualizado» deja la pregunta sin contestar. Tampoco la resuelve «el WAF lo bloquea», y en ese caso conviene insistir en el estado del parche. El ticket debería conservarse como evidencia, junto con las comprobaciones posteriores.
¿Cómo se actualiza un VPS sin confundir el PHP de consola con el de la web?
Antes de actualizar hay que inventariar paquetes, servicios y la asignación de cada dominio. La versión que muestra la terminal puede no coincidir con la que usan Apache o PHP-FPM.
En sistemas Debian o Ubuntu gestionados con APT, estos comandos solo consultan, sin modificar nada:
php -v
php --ini
dpkg-query -W 'php*' 'libapache2-mod-php*'
systemctl list-units --type=service --all 'php*-fpm.service'
php -v identifica únicamente el ejecutable de línea de comandos. El socket o el backend de cada virtual host hay que buscarlo en la configuración del servidor web. Conviene recordar, además, que algunos paneles instalan sus propios binarios al margen del gestor de paquetes del sistema.
El siguiente ejemplo solo es válido para Ubuntu 24.04 con PHP 8.3-FPM de los repositorios oficiales y sin un panel que gestione PHP. En cualquier otro servidor habrá que adaptar paquetes y servicios a lo que haya revelado el inventario:
sudo apt-get update
apt-cache policy php8.3-fpm php8.3-common
sudo apt-get -s install --only-upgrade php8.3-fpm php8.3-common
Antes de continuar, debe comprobarse que la versión candidata incluye el parche y revisarse la simulación. Si el aviso del proveedor señala otros paquetes PHP instalados como afectados, habrá que incluirlos. Después:
sudo apt-get install --only-upgrade php8.3-fpm php8.3-common
sudo php-fpm8.3 -t
sudo systemctl restart php8.3-fpm
systemctl is-active php8.3-fpm
El reinicio puede cortar peticiones en curso, así que, si hay varias réplicas, lo recomendable es retirarlas del balanceo y actualizarlas por turnos. Si la prueba de configuración falla, el error debe resolverse antes de reiniciar. Con mod_php el procedimiento es otro: hay que actualizar el módulo de Apache y reiniciar Apache, porque reiniciar FPM no lo cambia. Y en los servidores administrados con un panel, lo adecuado es seguir el mecanismo del propio panel para no mezclar repositorios.
En Debian, RHEL, sus derivados o las instalaciones compiladas a mano, la referencia son el aviso y los paquetes de cada proveedor. Que APT o DNF no encuentren actualizaciones no demuestra que el parche esté instalado; puede faltar el repositorio, la revisión o directamente el soporte.
¿Cómo se resuelve en Docker, Kubernetes o Windows?
Hay que actualizar el artefacto que contiene PHP y sustituir los procesos que están en ejecución. Descargar una imagen nueva no renueva por sí solo el servicio activo.
En Docker, lo primero es averiguar de dónde procede PHP: una imagen oficial, una imagen de WordPress, una imagen propia o un binario integrado. A continuación debe elegirse una imagen cuya revisión corregida pueda acreditarse y cambiar la etiqueta o el digest fijado, ya que volver a descargar un digest antiguo devuelve exactamente el mismo artefacto.
Para un servicio de Compose llamado web que ya apunte a la imagen corregida y guarde sus datos en volúmenes persistentes:
docker compose pull web
docker compose up -d --no-deps --force-recreate web
docker compose ps web
La propia documentación de Docker aclara que compose pull solo descarga la imagen; el contenedor hay que recrearlo. Con imágenes propias, el proceso pasa por actualizar la imagen base, reconstruir y desplegar. No debe usarse down -v, que borra los volúmenes y no tiene nada que ver con el parcheo.
En Kubernetes se actualiza el digest del workload, se sigue el despliegue y se verifican todas las réplicas, manteniendo las políticas de disponibilidad que ya estén probadas. Que una réplica muestre la versión nueva no significa que el clúster entero esté corregido.
En Windows con IIS, el primer paso es localizar el ejecutable de FastCGI que se usa de verdad. Después se instala la compilación corregida que corresponda a la arquitectura, a la variante TS o NTS y a las extensiones necesarias, se conserva la configuración y se reinician los procesos asociados. Sustituir DLL sueltas procedentes de otra compilación es mala idea. En los productos empaquetados, el paquete actualizado debe pedirse al fabricante.
¿Qué medidas urgentes pueden aplicarse si no es posible actualizar hoy?
Lo primero es aislar el servicio, si se puede. Cuando la web deba seguir abierta, se aplican las medidas oficiales de cada CVE en la configuración de arranque y se reinician todos los procesos.
El aviso de seguridad de PHP es claro: solo la actualización resuelve el problema por completo. Las medidas que siguen bloquean vías de ataque concretas, pero no convierten la instalación en segura. Conviene tratarlas como un puente de horas o de pocos días y dejar constancia de quién las aplica, cuándo y en qué fecha deben retirarse.
1. Bloquear las peticiones antes de que lleguen a PHP
CERT-EU recomienda aislar el servicio cuando no sea posible corregirlo de inmediato. La opción que propone ekko es una página estática de mantenimiento o una restricción por IP en el proxy o en el servidor web, comprobando antes que no quede expuesto ningún origen ni puerto alternativo.
Un plugin de mantenimiento llega tarde. Con mod_php, el primer fallo se desencadena antes de que se ejecute el código de la aplicación, y lo mismo vale para un acceso protegido únicamente desde la propia aplicación.
Si el sitio funciona con mod_php y el parche va a demorarse, trasladarlo a PHP-FPM elimina la vía de ataque demostrada que no depende de la aplicación, porque FPM termina el proceso cuando falla el arranque de la petición. Esta es una conclusión de ekko a partir del aviso, no una recomendación de PHP. FPM sigue siendo vulnerable, de modo que el cambio reduce el riesgo pero no ocupa el lugar del parche.
2. Contra CVE-2026-109618 (falta de memoria)
Estos son los criterios del aviso de PHP y de su aviso técnico:
- Fijar
memory_limit=-1de manera que la aplicación no pueda modificarlo, mediantephp_admin_valueen el pool de FPM o en la configuración de Apache, y verificar que ningún pool, directorio o aplicación vuelva a imponer un límite finito. Así desaparece el fallo de memoria que controla el atacante, si bien un fallo de asignación real seguiría alcanzando la ruta vulnerable. - Reducir
post_max_sizea 8M cuando la aplicación no reciba archivos y a 32M cuando los necesite, conupload_max_filesizesiempre por debajo de ese valor. - Limitar en el servidor web o en el proxy el tamaño decodificado de la petición, el número de campos, de partes multipart y de cabeceras por parte, así como la profundidad de anidamiento. Estos límites deben aplicarse también a las peticiones que no traigan un
Content-Lengthutilizable. En PHP, además, conviene reducirmax_input_nesting_levely no aumentarmax_input_vars. - Bloquear en el frontal los envíos
multipart/form-datacuando la aplicación no los use, de forma que nunca lleguen a PHP. - Establecer un límite de memoria de contenedor o de cgroup como garantía de disponibilidad, preferiblemente con una política que finalice solo el proceso afectado.
- No recurrir nunca a
RLIMIT_ASni aRLIMIT_DATA, que provocan precisamente el fallo de asignación por la ruta vulnerable.
Aplicar memory_limit=-1 de forma aislada sería un error: cambiaría una ejecución remota de código por una caída del servicio, ya que un único cliente podría agotar la memoria del servidor. Las medidas funcionan en conjunto.
3. Contra CVE-2026-109619 (estado global obsoleto)
Criterios del aviso de PHP y de su aviso técnico:
- Desactivar
session.upload_progress.enabled(valor0) enphp.ini, en el pool de FPM o en la configuración del servidor, y reiniciar todos los procesos. Con ello se cierran las vías confirmadas a través de las sesiones, aunque no las demás variantes. Muy pocas webs utilizan esta función, y PHP sugiere mantenerla desactivada incluso después de parchear. - En PHP 8.5, fijar
fatal_error_backtraces=0y reiniciar todos los procesos. Así se bloquea el caso mejor documentado, que es la base del ataque demostrado contramod_php. - Eliminar las directivas inválidas u obsoletas que se aplican en cada petición y generan avisos antes de la inicialización. El apartado siguiente explica cómo encontrarlas.
- Corregir los errores fatales y los tiempos de ejecución agotados que un visitante pueda provocar, incluidos los que surjan en callbacks, subidas, importaciones, páginas de error o tareas de limpieza.
- Valorar
pm.max_requests=1si el rendimiento no es prioritario. Con este ajuste cada proceso FPM atiende una sola petición y el estado no pasa de una a otra, a cambio de un consumo de CPU elevado; solo tiene sentido en webs con poco tráfico.
No sirven como protección temprana ni ini_set() desde la aplicación ni el .user.ini de FPM, que se aplica después de la inicialización. Tampoco ayuda ocultar los avisos con error_reporting, display_errors o @, porque el estado se lee antes de que PHP decida si muestra el mensaje. Y un plugin de seguridad de WordPress queda igualmente fuera de juego.
Ejemplo para PHP-FPM en Debian o Ubuntu
Las líneas siguientes se añaden al final del pool que atiende el dominio, por ejemplo /etc/php/8.3/fpm/pool.d/www.conf. Es un punto de partida y no una receta universal; si la web recibe archivos, los tamaños deberán ajustarse.
; Medidas temporales CVE-2026-109618 y CVE-2026-109619
; Responsable: ___ Aplicado: ___ Retirar o revisar tras el parche
php_admin_value[memory_limit] = -1
php_admin_value[post_max_size] = 8M
php_admin_value[upload_max_filesize] = 6M
php_admin_flag[session.upload_progress.enabled] = off
; Solo en PHP 8.5:
; php_admin_flag[fatal_error_backtraces] = off
El límite de memoria del servicio puede fijarse con un archivo complementario de systemd en /etc/systemd/system/php8.3-fpm.service.d/memoria.conf:
[Service]
MemoryMax=2G
OOMPolicy=continue
MemoryMax marca el techo de todo el servicio y debe ajustarse a la memoria del servidor. La directiva que realmente importa es OOMPolicy=continue. Con la política por defecto de systemd, si el kernel finaliza un proceso por falta de memoria, se detiene el servicio completo; con esta, solo cae el proceso afectado y el proceso principal de FPM lo sustituye. A continuación:
sudo php-fpm8.3 -t
sudo systemctl daemon-reload
sudo systemctl restart php8.3-fpm
Ejemplo para Apache con mod_php
Estas directivas van en el VirtualHost o en apache2.conf, nunca en .htaccess:
<IfModule php_module>
php_admin_value memory_limit -1
php_admin_value post_max_size 8M
php_admin_value upload_max_filesize 6M
php_admin_flag session.upload_progress.enabled off
</IfModule>
Con mod_php, esta configuración se aplica en cada petición, y un valor mal escrito generaría justo el tipo de aviso temprano que aprovecha el segundo fallo. Por eso conviene copiar los valores tal como aparecen, reiniciar con sudo apachectl configtest && sudo systemctl restart apache2 y confirmar en el registro de errores que no haya aparecido ningún aviso nuevo.
Ejemplo de límites en nginx
# En el bloque server {} que entrega las peticiones a PHP
client_max_body_size 8m;
location ~ \.php$ {
# Solo si la web no recibe formularios con archivos
if ($content_type ~* "multipart/form-data") { return 415; }
# ... fastcgi_pass y resto de la configuración existente
}
client_max_body_size limita también los cuerpos enviados por fragmentos, sin Content-Length. Su equivalente en Apache es LimitRequestBody. En cambio, ni nginx ni Apache permiten limitar con sus directivas estándar el número de partes, las cabeceras por parte o la profundidad de anidamiento; para eso hace falta un WAF capaz de inspeccionar envíos multipart. Cuando no se disponga de él y la web no reciba archivos, bloquear multipart cubre esos tres límites de una vez. En WordPress hay que tener en cuenta que la biblioteca de medios del panel usa multipart. Caben dos opciones: restringir /wp-admin/ por IP y dejarlo fuera del bloqueo, o renunciar a subir archivos mientras duren las medidas.
¿Cómo se localiza la configuración que activa el segundo fallo?
Hay que buscar directivas de PHP que se apliquen en cada petición y generen avisos. Cualquier aviso previo a la inicialización, aunque no se muestre ni quede registrado, puede consumir el estado obsoleto.
De acuerdo con el aviso técnico, la configuración por petición llega por estas vías:
- En
mod_php, a través de.htaccessy de las directivasphp_value,php_flagyphp_admin_*que Apache aplica por directorio. Es la vía más directa. - En PHP-FPM, solo cuando nginx,
mod_proxy_fcgiu otro frontal envíanPHP_VALUEoPHP_ADMIN_VALUE, algo que algunos paneles hacen de forma automática. Los valores del pool se aplican al arrancar cada proceso y.user.inidespués de la inicialización, por lo que ninguno de los dos entra en esta categoría. - En LiteSpeed (LSAPI), que puede aplicar pronto valores INI tomados del entorno, por lo que se considera un caso posible aunque no confirmado.
- El
php.ininormal se lee al arrancar y no vuelve a aplicarse en cada petición.
En Debian o Ubuntu, el inventario puede hacerse así (si un panel guarda las webs en otra ubicación, como /home/*/public_html, habrá que cambiar las rutas):
grep -RInE 'php_(admin_)?(value|flag)' /etc/apache2 /var/www
grep -RInE 'PHP_(ADMIN_)?VALUE' /etc/nginx /etc/apache2
Según los ejemplos del aviso técnico, generan avisos los siguientes valores:
- Las directivas obsoletas:
auto_detect_line_endings=1; unfilter.defaultdistinto del predeterminado; desde 8.3, las directivasassert.*heredadas; desde 8.4, las de sesión heredadas, comosession.sid_lengthosession.sid_bits_per_character; y en 8.5,report_memleaks=0o unintl.error_leveldistinto de cero. - Cualquier valor explícito en
mbstring.http_input,mbstring.http_output,mbstring.internal_encoding,iconv.input_encoding,iconv.output_encodingoiconv.internal_encoding. - Los valores inválidos o contradictorios en
zend.assertions,memory_limit,date.timezone, DBA, EXIF, correo, OpenSSL, zlib y las extensiones cargadas. - Desde PHP 8.2, las cantidades mal escritas o desbordadas de memoria, tamaño del cuerpo, entrada, tiempos o pila. Un
php_value upload_max_filesize 64Mcorrecto no genera ningún aviso; escrito como64MB, sí. - Las rutas de registro, correo, sesión o caché de SOAP que
open_basedirrechace.
La configuración legítima debería trasladarse a php.ini o al pool de FPM, que se aplican al arrancar, y las directivas obsoletas, eliminarse.
Revisión de los registros. En una copia aislada, o durante una ventana controlada, se activan en la configuración de arranque log_errors=On, un error_log operativo y error_reporting=E_ALL. Después se revisan los registros de Apache, PHP-FPM, el proxy y el sistema en busca de:
- avisos, deprecaciones y errores del núcleo que se repitan antes de que se ejecute el script;
- avisos emitidos durante la limpieza de extensiones o del servidor;
- errores fatales, de sintaxis y excepciones no capturadas;
- mensajes
Maximum execution time exceeded; - fallos que solo aparezcan en rutas, tipos de contenido, archivos u opciones de plugin que pueda controlar un visitante.
Corregir lo que aparezca es necesario, pero un registro limpio no garantiza nada. El histórico puede haberse recogido sin las deprecaciones, E_ALL solo cubre las rutas que se hayan recorrido durante la prueba y un fallo puede producirse antes de que PHP llegue a escribir el mensaje. Esta revisión complementa el parche y no permite dar por cerrada la incidencia.
¿Cómo se comprueba que la corrección está completa?
La incidencia se cierra con evidencias del paquete corregido, del reinicio de los procesos y del funcionamiento de cada dominio. Que la portada cargue no es suficiente.
ekko propone registrar, para cada dominio, lo siguiente:
| Evidencia | Qué conservar |
|---|---|
| Intérprete | SAPI, versión y ruta del servicio real |
| Corrección | Revisión completa del paquete o digest, y aviso que cubre ambos CVE |
| Activación | Hora del reinicio o del despliegue y réplicas comprobadas |
| Medidas temporales | Directivas aplicadas, ubicación, hora y fecha prevista de retirada |
| Funcionamiento | Acceso, formularios, subidas, tareas programadas y compra de prueba, si procede |
| Responsable | Persona o ticket del proveedor, y hora de la validación |
Para la comprobación puede usarse una pantalla de diagnóstico ya existente y restringida, o bien un endpoint temporal protegido en el propio servidor web, de forma que ninguna petición sin autorizar llegue a PHP. Si hace falta un código mínimo para ese endpoint:
<?php
header('Content-Type: text/plain; charset=utf-8');
echo PHP_VERSION, "\n", PHP_SAPI, "\n";
foreach ([
'memory_limit',
'post_max_size',
'upload_max_filesize',
'session.upload_progress.enabled',
'fatal_error_backtraces',
] as $k) {
echo $k, ' = ', var_export(ini_get($k), true), "\n";
}
Las líneas con ini_get() muestran los valores que aplica realmente el proceso web, no los de la terminal, y permiten confirmar en cada backend que las medidas temporales están activas. fatal_error_backtraces solo existe en 8.5; en ramas anteriores el resultado será false. La consulta debe hacerse sin caché y en cada backend, y el endpoint tiene que eliminarse al terminar. Publicar phpinfo() no es una alternativa aceptable. El número de versión, además, ha de cotejarse con el paquete, porque por sí solo no revela los backports; y en un entorno con balanceador, una petición aislada no verifica todos los nodos.
Si la actualización rompe alguna función, lo correcto es mantener restringido el servicio mientras se resuelve la incompatibilidad. Volver a la versión vulnerable y reabrir la web no puede considerarse una solución.
¿Qué hacer si se sospecha una intrusión previa?
El parche cierra la vulnerabilidad, pero no deshace una intrusión anterior. Antes de limpiar o reconstruir, conviene aislar el servicio y preservar las pruebas.
Como procedimiento, deberían conservarse los registros del proxy, del servidor y de PHP, el inventario de procesos, los cambios en el sistema de archivos y la actividad del panel, con sus marcas de tiempo y su zona horaria. Una instantánea del servidor resulta útil, aunque no demuestra que el sistema esté limpio.
El siguiente paso es buscar desviaciones respecto al comportamiento habitual: procesos hijos inesperados, conexiones salientes desconocidas, archivos nuevos, usuarios o tareas programadas que nadie haya autorizado. Son señales de carácter general y no indicadores exclusivos de estos CVE. Un error de memoria aislado no demuestra que haya habido explotación, del mismo modo que la ausencia de errores tampoco demuestra que el sistema sea seguro.
Si se confirma el compromiso, lo indicado es reconstruir desde una base de confianza, restaurar datos verificados y cambiar, desde un entorno limpio, todas las credenciales a las que tuviera acceso el servicio afectado. Un análisis de los archivos de WordPress no cubre necesariamente el resto del sistema, y en un caso así debería intervenir quien se encargue de la respuesta a incidentes.
¿Por qué la web de ekko no está expuesta a estos fallos?
La web de ekko genera su HTML durante la compilación y no necesita PHP para servir las páginas, de modo que el intérprete vulnerable no interviene en ninguna visita.
En este proyecto, astro.config.mjs declara output: 'static' y no incorpora ningún adaptador de ejecución. El contenido se valida y se compila antes de publicarse, y el resultado es un conjunto de archivos que el servidor entrega sin arrancar un CMS, consultar una base de datos ni interpretar PHP en cada visita.
La protección frente a estos dos fallos procede únicamente de prescindir de PHP para servir estas páginas. La política de seguridad de contenidos, los recursos locales y la ausencia de JavaScript de framework forman parte de la disciplina técnica de ekko, pero no protegen frente a una vulnerabilidad del intérprete.
Conviene precisar el alcance. El código del sitio no acredita que en el alojamiento no haya PHP, ni que un webmail, un panel o un dominio vecino estén corregidos; esos componentes deben inventariarse y aislarse por separado. Una web estática sigue necesitando proteger el servidor, el DNS, las credenciales y la cadena de publicación. Tampoco se afirma que todos los proyectos de los clientes de ekko compartan esta arquitectura.
El principio que sigue ekko es no mantener en producción capacidades que el negocio no necesite. Cuando hay pagos, cuentas de usuario o procesos dinámicos, se diseñan con límites y un mantenimiento definidos. Cuando solo se trata de publicar contenido, no tiene sentido añadir un intérprete accesible desde internet que reconstruya cada página en cada petición.
Para quien depende hoy de PHP, la prioridad es parchear y verificar, y no migrar con prisas en plena emergencia. Una vez superada la urgencia, ekko puede revisar qué partes de una web necesitan realmente ejecución dinámica y cuáles pueden convertirse en archivos estáticos, con el objetivo de reducir mantenimiento y superficie de ataque mediante decisiones que puedan comprobarse.
¿Qué más se pregunta sobre este tema?
¿Qué es CVE-2026-109618?
Es una vulnerabilidad crítica de PHP, con CVSS v4.0 de 9,2 y aviso GHSA-w8hw-w9fx-j79w, publicada como «RCE via OOM corruption». Cuando una petición agota la memoria, PHP puede quedarse con datos internos a medio inicializar y usarlos después, al cerrar la petición. Eso permite ejecutar código sin autenticación; en Apache con mod_php llegó a demostrarse antes de que arrancara la aplicación. Queda corregida en PHP 8.5.12, 8.4.27, 8.3.36 y 8.2.35.
¿Qué es CVE-2026-109619?
Es una vulnerabilidad crítica de PHP, con CVSS v4.0 de 9,2 y aviso GHSA-6wmf-4rv5-p3rp, publicada como «RCE via stale global state». Un proceso de PHP conserva referencias a la memoria de una petición ya liberada y la siguiente petición que atiende las utiliza. Se trata de un use-after-free que permite ejecutar código sin autenticación y filtrar memoria, con explotación validada en mod_php y en PHP-FPM. Se corrige en las mismas versiones que la anterior.
¿Qué versiones de PHP corrigen CVE-2026-109618 y CVE-2026-109619?
Las versiones 8.5.12, 8.4.27, 8.3.36 y 8.2.35, publicadas el 21 de octubre de 2026. Las distribuciones Linux pueden incorporar la corrección sobre un número base más antiguo, con una revisión de paquete nueva; es el caso de Ubuntu 24.04 con 8.3.6-0ubuntu0.24.04.13. Para PHP 8.1 y anteriores no hay versión oficial, de modo que hace falta un backport del proveedor o un cambio de rama.
¿Afecta a PHP-FPM o solo a Apache con mod_php?
Afecta a cualquier instalación que atienda peticiones web, ya sea con PHP-FPM, mod_php, php-cgi, FrankenPHP o LiteSpeed. El riesgo es mayor en mod_php, porque allí el primer fallo puede explotarse antes de que se ejecute la aplicación. En PHP-FPM existe explotación validada del segundo fallo, y el primero se considera igualmente aprovechable.
¿Actualizar WordPress protege de estas vulnerabilidades?
No. El fallo reside en el intérprete de PHP y no en WordPress ni en sus plugins, así que un WordPress al día sobre un PHP sin parchear sigue expuesto. Lo que debe actualizarse es el paquete de PHP que ejecuta la web, con un reinicio posterior de todos sus procesos. Ocurre lo mismo con PrestaShop, Laravel, Drupal o cualquier otra aplicación PHP.
¿Qué hacer si no es posible actualizar PHP hoy?
Lo prudente es aislar el servicio antes de que las peticiones lleguen a PHP. Si la web tiene que seguir abierta, PHP propone varias medidas en la configuración de arranque: session.upload_progress.enabled=0, fatal_error_backtraces=0 en PHP 8.5 y memory_limit=-1 fijado con php_admin_value, acompañado de un post_max_size bajo y de límites de petición en el proxy. Después hay que reiniciar todos los procesos. Reducen el riesgo, aunque no sustituyen el parche.
¿Están afectados PHP 7.4, 8.0 y 8.1?
Sí. Esas ramas ya no reciben versiones del proyecto PHP, pero, dada la gravedad, se han publicado parches mínimos de código fuente para 7.4, 8.0 y 8.1, pensados para quien compila PHP por su cuenta o carece de proveedor LTS. En un hosting, lo razonable es pedir al proveedor un backport acreditado o pasar a una rama con soporte.
¿Cómo saber qué versión de PHP usa realmente una web?
Ni php -v en la terminal ni el selector del panel sirven para esto, porque muestran el PHP de la línea de comandos o la rama elegida, no la revisión que atiende la web. Hay que revisar el servicio real de cada dominio (el socket de PHP-FPM, el módulo de Apache o LiteSpeed) y su paquete completo, o bien consultar un endpoint temporal y protegido que muestre PHP_VERSION y PHP_SAPI.