Fallo crítico en PHP (PHP2Shell): qué es y cómo corregirlo en Ubuntu con Apache o Nginx

Equipe Hcode21 de octubre de 202611 min de lectura

En este artículo

El 21 de octubre de 2026, el proyecto PHP lanzó las versiones 8.5.12, 8.4.27, 8.3.36 y 8.2.35. Corrigen dos fallas críticas, la CVE-2026-109618 y la CVE-2026-109619. Ambas recibieron una puntuación de 9.2 en el CVSS v4.0 y permiten la ejecución remota de código, es decir, un atacante puede ejecutar comandos en el servidor. Los investigadores denominaron el par de fallas PHP2Shell. Si tienes algún servidor con PHP, la solución es una sola: actualizar PHP y reiniciar los servicios que lo utilizan. En este artículo entenderás qué son las fallas, quién se ve afectado y verás una guía completa para un servidor Ubuntu con Apache o Nginx.

Qué sucedió

El 20 de octubre, el equipo de seguridad de PHP publicó un aviso anticipado: habría una versión de emergencia al día siguiente, a las 14:00 UTC (11:00 en hora de Brasilia), para corregir dos vulnerabilidades críticas. El equipo también dijo que podría adelantar el lanzamiento si los detalles se filtraban o si aparecían señales de explotación. Ese mismo día, el CERT-EU publicó una alerta, y el National Cyber Security Centre del Reino Unido también advirtió sobre el problema.

El 21, las versiones corregidas fueron lanzadas, y las distribuciones de Linux, que habían recibido las correcciones con anticipación, publicaron paquetes actualizados. Ubuntu, por ejemplo, lanzó el aviso de seguridad USN-8948-1.

Las dos fallas, en lenguaje sencillo

CVE-2026-109618: corrupción de memoria cuando falta memoria

Cuando una solicitud hace que PHP alcance el límite de memoria, el procesamiento puede interrumpirse mientras los datos internos de la solicitud aún están a medio camino. Luego, durante la limpieza de la solicitud, PHP trata esos datos incompletos como si fueran válidos. Un atacante puede provocar esta situación deliberadamente con una solicitud preparada. Según el equipo de PHP, la ejecución remota de código fue confirmada por HTTP en servidores con Apache y mod_php. Según el análisis del código, PHP-FPM también es vulnerable, pero no se había demostrado ninguna explotación completa a través de FPM hasta el lanzamiento.

CVE-2026-109619: estado antiguo reutilizado entre solicitudes

Los servidores reutilizan el mismo proceso (el worker) para atender varias solicitudes. Debido a esta falla, una información interna de una solicitud puede seguir existiendo después de que su memoria haya sido liberada, y la siguiente solicitud, en el mismo worker, puede usar ese dato antiguo. Es un caso de use-after-free. Los caminos confirmados involucran el tratamiento de sesiones y los backtraces de errores fatales. Además de ejecutar código, la falla puede filtrar datos de la memoria del servidor.

Quién se ve afectado

  • Cualquier instalación de PHP que atienda solicitudes web: PHP-FPM (común con Nginx), Apache con mod_php, php-cgi, FrankenPHP y LiteSpeed. El equipo de PHP considera que Apache con mod_php es el caso de mayor riesgo.
  • Versiones antiguas también. Según Laravel Forge, las fallas existen en versiones de PHP desde 2004.
  • Cualquier aplicación. El ataque ocurre antes de que se ejecute el código de la aplicación. Los investigadores dicen haber conseguido la ejecución de código sin inicio de sesión contra WordPress, Drupal y Joomla, y hasta contra un simple "Hello World".

Respecto a la explotación: el equipo de PHP dijo no haber identificado exploits funcionales hasta el lanzamiento. El CERT-EU informó que comenzaron a circular pruebas de concepto, y Cloudflare notificó haber visto tráfico de ataque contra sus clientes. Por eso, trata la actualización como urgente.

Versiones corregidas

Rama de PHPVersión corregidaEstado de la rama
8.58.5.12Soporte activo
8.48.4.27Soporte activo
8.38.3.36Solo correcciones de seguridad, hasta 31/12/2027
8.28.2.35Solo correcciones de seguridad, hasta 31/12/2026
8.1 o anteriorSin corrección oficial de PHPFin de vida

Atención: en Ubuntu, el número de versión puede ser diferente

Este es el punto que más confunde. Los paquetes oficiales de Ubuntu no cambian la versión de PHP: aplican la corrección a la versión que la distribución ya usa (el llamado backport). Por eso, un Ubuntu 24.04 corregido sigue mostrando PHP 8.3.6 en el php -v, y no 8.3.36. Lo que cambia es la revisión del paquete. Estas son las versiones corregidas según la USN-8948-1:

UbuntuPaqueteVersión corregida del paquete
26.10php8.58.5.9-0ubuntu2.1
26.04 LTSphp8.58.5.4-0ubuntu1.5
24.04 LTSphp8.38.3.6-0ubuntu0.24.04.13
22.04 LTSphp8.18.1.2-1ubuntu2.28

Ten en cuenta que Ubuntu 22.04 corrigió PHP 8.1, incluso cuando esta rama no recibe más correcciones del proyecto PHP. Ubuntu 20.04 y las versiones más antiguas también recibieron corrección, pero solo a través del ESM, que requiere Ubuntu Pro (gratuito para hasta 5 máquinas).

Si instalaste PHP a través del repositorio de Ondřej Surý (el PPA ondrej/php, muy utilizado para tener versiones más nuevas), entonces la versión seguirá la del PHP, como 8.4.27. Y vale la pena un aviso: las actualizaciones automáticas de Ubuntu (unattended-upgrades) aplican solo lo que proviene del repositorio de seguridad de Ubuntu. Quien usa el PPA debe actualizar manualmente.

Pasos a paso: cómo corregir en Ubuntu con Apache o Nginx

Los comandos a continuación utilizan PHP 8.3 como ejemplo. Cambia 8.3 por la versión de tu servidor. Ejecuta todo con un usuario que tenga sudo.

1. Descubre qué versiones de PHP están instaladas

php -v
ls /etc/php
dpkg -l 'php*' 'libapache2-mod-php*' | awk '/^ii/ {print $2, $3}'

El último comando lista cada paquete de PHP con la versión instalada. Anota el resultado para comparar después. Si aparece más de una versión en /etc/php, actualiza todas, incluidas las que ningún sitio usa hoy.

2. Descubre cómo se ejecuta PHP

Esto define qué servicio vas a reiniciar al final.

Apache:

apache2ctl -M 2>/dev/null | grep -E 'php|proxy_fcgi'
ls /etc/apache2/conf-enabled | grep -i fpm
  • Si aparece php_module (o php8.3_module), Apache usa mod_php.
  • Si aparece proxy_fcgi_module y un archivo como php8.3-fpm.conf, Apache usa PHP-FPM.

Nginx: Nginx siempre usa PHP-FPM. Ve qué versión llama cada sitio:

grep -R "fastcgi_pass" /etc/nginx/sites-enabled/ /etc/nginx/conf.d/ 2>/dev/null

Una línea como fastcgi_pass unix:/run/php/php8.3-fpm.sock; indica que el sitio usa PHP-FPM 8.3.

3. Descubre de dónde viene el paquete

sudo apt update
apt-cache policy php8.3-cli
ls /etc/apt/sources.list.d/

En la salida de apt-cache policy, ve la línea Candidate y el origen. Si proviene de ppa.launchpadcontent.net/ondrej/php o packages.sury.org, PHP proviene del repositorio de Ondřej, y la versión candidata debe ser la del proyecto PHP (por ejemplo, 8.3.36). Si proviene de security.ubuntu.com o archive.ubuntu.com, compara con la tabla de Ubuntu anterior. Si la versión candidata aún no es la corregida, el paquete aún no ha llegado al repositorio: espera un poco y ejecuta sudo apt update de nuevo.

4. Haz una copia de seguridad

Antes de alterar en producción, haz una copia de seguridad de los archivos del sitio, de la base de datos y de las configuraciones de PHP. Un ejemplo simple:

sudo tar czf /root/backup-php-config-$(date +%F).tar.gz /etc/php /etc/apache2 /etc/nginx 2>/dev/null

Si el servidor es una VM en la nube, tomar un snapshot del disco es aún mejor. Y si tienes un ambiente de homologación, aplica la actualización allí primero.

5. Actualiza los paquetes de PHP

Este comando actualiza todos los paquetes de PHP ya instalados, sin instalar nada nuevo. La opción --force-confold mantiene tu php.ini y las configuraciones del FPM:

sudo apt-get install --only-upgrade -y \
  -o Dpkg::Options::="--force-confold" \
  $(dpkg -l 'php*' 'libapache2-mod-php*' | awk '/^ii/ {print $2}')

Si prefieres, sudo apt update && sudo apt upgrade actualiza todo el sistema, lo cual también es recomendado por Ubuntu.

6. Reinicia los servicios

Actualizar el paquete no es suficiente: el proceso que ya estaba en ejecución sigue con el código antiguo en memoria hasta que se reinicie. Elige tu caso:

Apache con mod_php:

sudo systemctl restart apache2

Apache o Nginx con PHP-FPM (repite para cada versión instalada):

sudo systemctl restart php8.3-fpm

Con PHP-FPM, no es necesario reiniciar Apache ni Nginx, ya que solo reenvían las solicitudes al FPM. El reinicio puede interrumpir el sitio por algunos segundos, así que elige un horario de poco acceso.

Procesos PHP de larga duración: colas, workers del Supervisor, Laravel Horizon, Octane o cualquier script que se ejecute continuamente por la línea de comandos seguirán con la versión antigua hasta que se reinicien. En Laravel, por ejemplo:

php artisan queue:restart
php artisan horizon:terminate
sudo supervisorctl restart all

Si no sabes todo lo que se ejecuta en el servidor, reiniciar la máquina (sudo reboot) resuelve de una vez.

7. Confirma que la corrección está activa

dpkg -l 'php*' 'libapache2-mod-php*' | awk '/^ii/ {print $2, $3}'
php -v
php-fpm8.3 -v
systemctl status php8.3-fpm --no-pager | head -5

Verifica si las versiones coinciden con la tabla correspondiente (del PHP, si usas el PPA; de Ubuntu, si usas los paquetes oficiales) y si el servicio se inició después de la actualización. En los paquetes oficiales de Ubuntu, también puedes buscar las CVEs en el changelog:

apt changelog php8.3-fpm 2>/dev/null | grep -m2 -E 'CVE-2026-10961[89]'

Por último, abre el sitio y verifica si todo funciona con normalidad.

¿Y si aún uso PHP 8.1 o anterior?

El proyecto PHP no corregirá estas ramas. Tus opciones son:

  • Ubuntu 22.04 con el PHP 8.1 oficial: Ubuntu ya lo corrigió. Solo necesitas seguir el paso a paso.
  • Ubuntu 20.04 o anterior: activa Ubuntu Pro para recibir la corrección a través del ESM y planifica la migración a una versión soportada.
  • PHP antiguo proveniente de otra fuente: migra a una versión soportada (8.3 o más nueva) tan pronto como sea posible. Prueba primero, porque plugins y bibliotecas antiguos pueden fallar en versiones nuevas.

Si no se puede actualizar ahora

El equipo de PHP es claro: no existe mitigación completa, solo la actualización resuelve. Mientras tanto, algunas medidas reducen el riesgo:

  • Desactiva el progreso de carga de sesiones en el php.ini o en el pool del FPM con session.upload_progress.enabled = 0 y reinicia todos los workers. Hacerlo con ini_set() o .user.ini no funciona.
  • Reduce el tamaño máximo de las solicitudes: post_max_size de 8M si el sitio no recibe cargas, o 32M si las recibe, con upload_max_filesize menor que él. En el servidor web, ajusta client_max_body_size (Nginx) o LimitRequestBody (Apache) en el mismo sentido.
  • En PHP 8.5, establece fatal_error_backtraces = 0.
  • Si el sitio pasa por Cloudflare, han publicado reglas de WAF para los vectores conocidos, incluso en el plan gratuito. Es una protección paliativa y solo es válida para el tráfico que pasa a través de ella.

El CERT-EU también recomienda, en los casos más críticos, retirar la aplicación del acceso público hasta la corrección.

Vale la pena verificar si hubo intrusiones

Si el servidor estuvo expuesto con una versión vulnerable, haz una verificación rápida después de actualizar:

# Archivos PHP modificados en los últimos 7 días
sudo find /var/www -name "*.php" -mtime -7 -not -path "*/cache/*"

# Últimos inicios de sesión y tareas programadas
last -n 20
sudo crontab -l; ls /etc/cron.d

Verifica también si hay nuevos usuarios administradores en la aplicación (en WordPress, en Usuarios) y solicitudes extrañas en los registros de acceso de Apache o Nginx. Hasta la publicación de este artículo, ni PHP ni las agencias de seguridad habían divulgado indicadores de compromiso específicos.

¿Y quienes usan WordPress?

La falla está en PHP, y no en WordPress. Actualizar WordPress, los plugins o los temas no corrige el problema. En el hospedaje compartido o administrado, quien actualiza PHP es el proveedor: confírmalo con él. En VPS o servidor propio, sigue el paso a paso anterior. Para ver la versión de PHP a través del panel, ve a Herramientas, Salud del Sitio, pestaña Información, sección Servidor.

Conclusión

Las fallas CVE-2026-109618 y CVE-2026-109619 afectan prácticamente a cualquier servidor con PHP, y la única corrección completa es actualizar. En resumen: descubre la versión y el origen de los paquetes, haz una copia de seguridad, actualiza, reinicia Apache o PHP-FPM y los workers, y confirma la versión. Si tu servidor aún ejecuta PHP 8.1 o anterior, aprovecha el susto para planificar la migración.

¿Quieres profundizar en PHP y servidores Linux? Conoce los cursos de la plataforma de Hcode y sigue el blog.

Preguntas frecuentes

¿Mi Ubuntu muestra PHP 8.3.6. Estoy vulnerable?

No necesariamente. En los paquetes oficiales de Ubuntu 24.04, la corrección llega en la revisión del paquete 8.3.6-0ubuntu0.24.04.13. Verifica la versión completa del paquete con dpkg -l 'php8.3*', y no solo php -v.

¿Necesito reiniciar Nginx?

No. Con Nginx, quien ejecuta PHP es PHP-FPM, así que basta con reiniciar el servicio php8.x-fpm. Con Apache y mod_php, reinicia apache2.

¿Las actualizaciones automáticas de Ubuntu resuelven?

Si usas los paquetes oficiales de Ubuntu y unattended-upgrades está activo, la corrección se aplica en hasta 24 horas, pero los servicios aún necesitan ser reiniciados. Si usas el PPA de Ondřej, la actualización automática no cubre PHP.

¿Cambiar configuraciones del php.ini resuelve?

No. Las configuraciones reducen el riesgo, pero el propio equipo de PHP afirma que la única mitigación completa es actualizar.

Fuentes

Sigue aprendiendo con Hcode

Regístrate en la plataforma de cursos y sigue las próximas guías del blog.