Situación actual: PHP2Shell. Dos vulnerabilidades críticas de PHP (CVSS 9.2) permiten ejecutar código malicioso sin autenticación. Parches desde el 21/10/2026.Qué hacer ahora →

Cómo genera PHP una página web: el recorrido de una petición

Qué ocurre entre el clic y la página terminada: servidor web, SAPI, compilador, OPcache y Zend VM en siete pasos, y por qué PHP2Shell actúa justo en este proceso.

Actualizado 5 min de lecturaConocimiento de PHP

En resumen: cuando un navegador solicita una página PHP, el servidor web acepta la petición y la pasa a PHP mediante una interfaz (SAPI). PHP traduce el script a bytecode, lo ejecuta en la Zend Engine y devuelve el resultado, normalmente HTML, al servidor web. Después se limpia el estado de la petición para que la siguiente empiece de forma limpia.

¿Qué ocurre cuando alguien visita su sitio web?

Para los visitantes es un clic. En el servidor se suceden muchos pasos en milisegundos. Quien conoce este proceso entiende mejor por qué son tan importantes las actualizaciones, los reinicios y la configuración, y por qué una vulnerabilidad en el propio PHP pesa más que una en un plugin.

El manual de PHP menciona tres componentes necesarios para un sitio web en PHP: el intérprete de PHP (como CGI o como módulo del servidor), un servidor web y un navegador. El intérprete es el programa que lee y ejecuta el código PHP. El modo de ejecución depende de cómo esté conectado al servidor web.

Cómo funciona PHP: siete pasos de una petición

  1. Petición: el navegador envía al servidor una petición HTTP, por ejemplo GET /kontakt.php.
  2. Servidor web: Apache, Nginx o LiteSpeed aceptan la petición. Los archivos estáticos, como las imágenes, los entregan ellos mismos. Para los archivos .php invocan a PHP.
  3. Traspaso mediante la SAPI: la interfaz del servidor (SAPI) entrega a PHP los datos de la petición, como cabeceras, parámetros y datos de formularios. En PHP-FPM esto se hace mediante el protocolo FastCGI; en mod_php, directamente en el proceso de Apache. Detalles en SAPI explicada.
  4. Preparar la petición: PHP guarda los datos de la petición en variables como $_GET, $_POST, $_COOKIE y $_FILES y reserva memoria para la petición.
  5. Traducir: el script se descompone en componentes (tokens), de ahí surge un árbol sintáctico abstracto (AST) y de este, los opcodes, una especie de lenguaje máquina para PHP. Si OPcache está activo, este paso se omite cuando el script ya está en la caché.
  6. Ejecutar: la máquina virtual de la Zend Engine procesa los opcodes, consulta bases de datos, lee archivos y genera la salida.
  7. Respuesta y limpieza: la salida vuelve al servidor web mediante la SAPI y de allí al navegador. A continuación, PHP libera la memoria de la petición y restablece el estado.

El AST existe desde PHP 7. Según el RFC correspondiente, antes el analizador generaba los opcodes directamente durante la lectura; la separación en tres fases hizo que el compilador fuera más fácil de mantener.

Un ejemplo: lo que el script ve de la petición

El siguiente script inofensivo muestra qué información recibe PHP de la petición y en qué modo de ejecución se ejecuta:

<?php
header('Content-Type: text/plain; charset=utf-8');

echo 'Betriebsart (SAPI): ' . PHP_SAPI . "\n";
echo 'PHP-Version: ' . PHP_VERSION . "\n";
echo 'Methode: ' . ($_SERVER['REQUEST_METHOD'] ?? '-') . "\n";
echo 'Speicher in dieser Anfrage: ' . memory_get_usage() . " Bytes\n";

En un servidor con PHP-FPM, PHP_SAPI devuelve el valor fpm-fcgi; en Apache con mod_php, apache2handler. Coloque estos archivos de prueba en el directorio público solo de forma breve y nunca de forma permanente, porque la información de versión también ayuda a los atacantes a orientarse.

Dónde intervienen la caché de bytecode y el JIT

La traducción del paso 5 cuesta tiempo. Según el manual, OPcache almacena bytecode precompilado en la memoria compartida y le ahorra así a PHP cargar y descomponer los scripts en cada petición. Desde PHP 8.0 puede además un compilador JIT generar código máquina real a partir de los opcodes. Según el RFC del JIT, es una parte casi independiente de OPcache.

Fase Resultado ¿Se guarda en caché?
Análisis léxico flujo de tokens no
Análisis sintáctico árbol sintáctico abstracto (AST) no
Compilación opcodes (op-arrays por archivo y función) sí, en OPcache
JIT (opcional) código máquina sí, en la memoria de OPcache
Ejecución salida de la página no

La caché solo afecta al código traducido. Los datos de cada petición, como las entradas de formularios o los valores de sesión, no se comparten a través de OPcache.

Por qué PHP2Shell actúa justo en este proceso

Las dos vulnerabilidades de PHP2Shell no afectan a una aplicación, sino al propio proceso. En CVE-2026-109618, un estado de falta de memoria puede interrumpir PHP mientras los datos de la petición solo están preparados en parte, es decir, en el paso 4. En la limpieza posterior, los datos no válidos pueden tratarse entonces como válidos.

En CVE-2026-109619, el estado interno de una petición puede persistir tras liberar la memoria. Una petición posterior en el mismo worker puede utilizarlo antes de que se restablezca. Esto afecta al paso 7, la limpieza. Los antecedentes están en la página CVE-2026-109619 y en el artículo sobre el ciclo de vida de la petición.

De ello se deduce: las medidas de protección en el código de la aplicación, como los plugins de seguridad, solo actúan en el paso 6. En mod_php, según el equipo de PHP, incluso se demostró un exploit antes de que se ejecutara siquiera código de la aplicación. Solo es eficaz la actualización de PHP a 8.5.12, 8.4.27, 8.3.36 o 8.2.35 y el reinicio de todos los procesos de PHP, porque, de lo contrario, los workers de larga duración siguen ejecutando el código antiguo.

¿Cómo ayuda PHP SOS en concreto?

  • Hacer visible el proceso: averiguamos qué modo de ejecución, qué configuración y qué caché están realmente activos en su servidor.
  • Actualizar correctamente: instalamos la actualización de PHP y comprobamos mediante las horas de inicio que ya no queda ningún proceso antiguo en ejecución.
  • Proteger las capas: en el marco del refuerzo del servidor limitamos los tamaños de las peticiones, la memoria y los permisos donde son eficaces: antes del código de la aplicación.
  • Revisar rastros: en los servidores que eran accesibles sin protección, buscamos indicios de una intrusión.

Preguntas frecuentes

¿Se traduce el código PHP de nuevo en cada acceso?

Sin caché, sí: PHP descompone el script, construye un árbol sintáctico y genera a partir de él los opcodes. Con OPcache activo, los opcodes quedan en la memoria compartida y se reutilizan mientras el archivo no haya cambiado.

¿Qué queda en memoria después de una petición?

En principio, el estado de una petición se limpia al final para que la siguiente empiece de forma limpia. Solo son duraderos elementos como OPcache o las conexiones persistentes. Justo en esta limpieza actúa CVE-2026-109619.

¿Por qué hay que reiniciar PHP después de una actualización?

En PHP-FPM y mod_php los procesos se ejecutan de forma permanente y han cargado el código de programa antiguo. Los archivos nuevos en el disco no cambian eso. Solo un reinicio carga el código corregido.

¿Es más seguro un servidor web sin PHP?

Tiene menos superficie de ataque, porque ninguna lógica de programa reacciona a las peticiones. Para contenidos puramente estáticos es una opción real. Pero para tiendas, formularios e inicios de sesión se necesita un lenguaje del lado del servidor, y entonces cuenta su mantenimiento.

Fuentes

Contacto inmediato

Cada hora cuenta. Escríbanos ahora.

Describa brevemente el sistema, la versión de PHP y lo que ha observado. Nos pondremos en contacto, aclararemos la situación y trabajaremos en remoto hasta que el incidente quede cerrado y documentado.

Ayuda inmediata