Tutorial

Inventario de versiones PHP de sitios cliente: método de agencia

Seguridad y monitorización11 min de lectura8 pasos

Cuando aparece un fallo crítico de PHP, la pregunta del cliente es simple: ¿mi sitio está afectado? Para una agencia, responder sitio por sitio, en cinco proveedores y con accesos desiguales, lleva días si nada está preparado. Este método cabe en media jornada para 20 a 200 sitios: medición por niveles según el acceso, un registro que separa lo presunto de lo confirmado, lotes de prioridad, un mensaje tipo y una prueba fechada de la corrección. El mismo registro se repite con cada CVE y con cada fin de vida de rama.

Contenido· Qué debe producir una auditoría de cartera1/14
  1. 01Qué debe producir una auditoría de cartera
  2. 02Contexto fechado: PHP2Shell
  3. 03Los cuatro niveles de medición
  4. 04Medir nivel por nivel
  5. 05Por qué no phpinfo, y nunca en público
  6. 06El registro: una fila por sitio
  7. 07Las columnas del registro
  8. 08Clasificar en lotes, no en una lista de la compra
  9. 09Cuadrícula de prioridad
  10. 10Avisar a los clientes sin alarmarlos
  11. 11Dos mensajes tipo
  12. 12Probar la corrección y repetir la auditoría
  13. 13La cadencia: una auditoría por trimestre y en cada desencadenante
  14. 14La documentación oficial

Qué debe producir una auditoría de cartera

Una auditoría de cartera no es un comando que se lanza una vez. Es un registro: una fila por sitio, con la versión PHP leída, cómo se leyó, la fecha y el grado de certeza. Sin estos tres datos una cifra no vale nada, porque una versión leída el mes pasado no dice nada del estado de hoy.

La objeción habitual es legítima: no controla el proveedor del cliente, no puede lanzar comandos SSH en todas partes y no debe dejar un archivo de diagnóstico en un sitio en producción. La respuesta es una idea: se mide con lo que se tiene y se anota con honestidad lo que prueba cada medición. Un sitio leído desde fuera es presunto; un sitio leído desde el servidor es confirmado. El registro conserva ambos y muestra dónde queda trabajo.

Contexto fechado: PHP2Shell

El 21 de octubre de 2026, el proyecto PHP publicó las versiones 8.5.12, 8.4.27, 8.3.36 y 8.2.35, que corrigen CVE-2026-109618 y CVE-2026-109619 (ejecución remota de código sin autenticación). PHP 8.1 y las ramas anteriores ya no reciben actualizaciones del proyecto; se publicaron retroportes mínimos del código fuente para 7.4, 8.0 y 8.1. La incorporación al catálogo de vulnerabilidades explotadas de CISA data del 26 de octubre de 2026, con un plazo federal al 29 de octubre de 2026. Los fallos y la actualización de un servidor se tratan en el artículo dedicado; aquí nos ocupamos de la cartera.

Los cuatro niveles de medición

Desplace la tabla

Nivel y accesoQué pruebaQué no prueba
1. Observación externa, sin accesoUna cabecera X-Powered-By o Server, cuando existe, sugiere una pila y una versiónNada seguro: la cabecera suele estar oculta, eliminada o ser falsa. Es una presunción
2. wp-cli o SSHLa versión del binario PHP de línea de comandos, leída en la máquinaLa versión servida en la web: el binario CLI puede diferir de PHP-FPM o Apache
3. Panel cPanel, WHM o PleskLa versión asignada a cada dominio, con su manejadorLa corrección realmente aplicada: el mismo número puede estar corregido o no según el paquete
4. DockerLa versión en la imagen y en el contenedor en ejecuciónQue la imagen desplegada sea la correcta: comparar imagen y contenedor vivo
Lectura del changelog del paqueteQue la corrección está presente aunque el número no cambie (retroporte)Que el sitio no fuera comprometido antes de la actualización
Ningún nivel posibleNada: el sitio pasa al lote 4, a pedir al cliente o al proveedorNo clasificarlo nunca como corregido por defecto

Medir nivel por nivel

  1. Nivel 1: leer las cabeceras sin acceso

    Prepare sites.txt, una URL por línea, y ejecute while read -r u; do printf '%s,%s\n' "$u" "$(curl -sI --max-time 10 "$u" | tr -d '\r' | grep -iE '^(server|x-powered-by):' | tr '\n' ' ')"; done < sites.txt > externe.csv. Cada línea da la URL y las dos cabeceras encontradas. Una línea vacía es información: la cabecera está oculta. Clasifique estos sitios como presuntos y pase al nivel siguiente en cuanto pueda.

  2. Nivel 2: consultar WordPress con wp-cli

    En un sitio WordPress con wp-cli instalado, wp cli info muestra, entre otras, una línea PHP binary y una línea PHP version. Para extraer la segunda: wp cli info | grep 'PHP version'. Tenga en cuenta que este valor describe el binario usado en línea de comandos. El servidor web puede funcionar con otra versión, sobre todo cuando el proveedor ofrece varias versiones por dominio. Para una comprobación fiable, compare con el nivel 3.

  3. Nivel 2 bis: un script SSH por lotes

    Con hotes.txt (un alias SSH por línea): while read -r h; do printf '%s,%s\n' "$h" "$(timeout 20 ssh -n -o BatchMode=yes -o ConnectTimeout=8 "$h" "php -r 'echo PHP_VERSION;'" 2>/dev/null || echo inconnue)"; done < hotes.txt > ssh.csv. El -n impide que ssh se trague la lista, BatchMode evita que un host pida contraseña y bloquee el bucle, timeout acota cada intento. Los hosts que fallan aparecen como "inconnue" en lugar de desaparecer: probado con un host que falla y otro que no responde, ambos aparecen en el CSV.

  4. Nivel 3: leer los paneles

    En cPanel, MultiPHP Manager lista cada dominio con su versión PHP, o la mención Inherited cuando sigue el valor del sistema. En WHM, la misma herramienta da la vista por cuenta. En Plesk, la versión y el manejador se configuran por dominio en Sitios web y dominios, sección de ajustes de PHP, según la versión de Plesk. Anote la versión mostrada y pase al paso siguiente para saber si la corrección está presente.

  5. Retroportes: leer el changelog, no solo el número

    Las distribuciones y los proveedores con CloudLinux suelen corregir sin cambiar el número original. AlmaLinux lo dice expresamente en su aviso: no se fíe de php -v, compare el paquete instalado con la versión corregida publicada, por ejemplo con rpm -q php-common. Para buscar una CVE en el historial del paquete: rpm -q --changelog php-common | grep CVE-2026-109618 en la familia RHEL, y apt changelog seguido del nombre del paquete en Debian y Ubuntu. Si la CVE no aparece en el historial, no está corregida en ese paquete.

  6. Nivel 4: contenedores

    Una imagen reciente no prueba que el contenedor en ejecución también lo sea. Compare la versión de la imagen con la del contenedor en ejecución y reconstruya si es necesario. El procedimiento completo está en el artículo sobre la reconstrucción de imágenes PHP, al que remitimos para no copiarlo.

Por qué no phpinfo, y nunca en público

El reflejo es dejar un archivo phpinfo() en el sitio. Lo muestra todo, pero también expone rutas, módulos y configuración del servidor a cualquiera que conozca la dirección, y un archivo olvidado se convierte en un punto de entrada para el reconocimiento. En el sitio de un cliente hay un segundo problema: modificar ese sitio sin mandato escrito es una falta, incluso solo para leer una versión.

Por defecto, descártelo. Si una situación lo impone, un archivo temporal debe cumplir cuatro condiciones: el acuerdo escrito del cliente, un nombre imprevisible, su eliminación inmediata tras la lectura y una anotación de la operación en el registro. En casi todos los casos, una medición de nivel 2 o 3 hace innecesario el archivo.

El registro: una fila por sitio

Basta una hoja de cálculo compartida, siempre que todos mantengan las mismas columnas. El objetivo es que un compañero pueda retomar la auditoría sin hacerle preguntas y que el cliente pueda recibir su fila tal cual.

Las columnas del registro

  • Sitio, cliente, proveedor — la identidad de la fila, con la URL canónica y el contacto técnico.
  • Tipo de acceso — ninguno, wp-cli, SSH, panel o Docker: lo que determina el nivel alcanzable.
  • Método de medición — el comando o la pantalla utilizados, para que la medición se pueda repetir idéntica.
  • Versión leída y SAPI — el número y el modo de ejecución (FPM, módulo Apache, CLI), porque el riesgo varía según el modo.
  • Fecha de medición — una versión sin fecha es una opinión.
  • Nivel de confianza — presunto (nivel 1) o confirmado (niveles 2 a 4), más la mención de retroporte si el changelog lo confirma.
  • Lote de prioridad y estado — del 1 al 4, luego pendiente, avisado, en curso, corregido o rechazado por el cliente.
  • Fecha y prueba de corrección — la captura, la salida del comando y el nombre del operador.

Clasificar en lotes, no en una lista de la compra

Cuando el registro está lleno, la pregunta ya no es «¿está todo al día?» sino «¿por dónde empezamos?». Cuatro lotes responden. El lote 1 agrupa los sitios expuestos en una rama que ya no recibe correcciones del proyecto PHP (8.1 y anteriores), salvo corrección de un proveedor confirmada por el changelog. El lote 2: rama aún soportada pero versión anterior a la corrección. El lote 3: rama corregida, por confirmar con una medición de nivel 2 o 3. El lote 4: sitio inalcanzable o versión desconocida.

Tres criterios hacen subir un sitio de lote: un formulario público, una tienda, datos personales o un complemento que acepta archivos enviados. Un sitio escaparate estático en el lote 2 va después de una tienda en el lote 3.

Cuadrícula de prioridad

Desplace la tabla

LoteCriterioAcción
Lote 1Expuesto, rama sin corrección del proyecto (8.1 y anteriores)Migrar o exigir un paquete corregido por el proveedor, avisar al cliente el mismo día
Lote 2Rama soportada, versión anterior a la correcciónActualizar a la versión corregida de la rama, dentro de la semana
Lote 3Rama corregida, medición por confirmarMedición de nivel 2 o 3 y luego pasar la confianza a confirmado
Lote 4Inalcanzable, acceso denegado o versión desconocidaPedir al cliente el acceso o la versión, insistir y fechar cada petición
AgravanteFormulario, tienda, datos personales, subida de archivosSube el sitio un lote en el orden de tratamiento

Avisar a los clientes sin alarmarlos

Un cliente no necesita el detalle de las dos CVE. Necesita saber si su sitio está afectado, qué hace usted y qué cambia para él. Bastan dos mensajes cortos, para adaptar. Mantenga el mismo tono factual: la versión leída, la fecha, lo que sigue. No escriba que el sitio está protegido o asegurado: una versión leída no es una prueba de ausencia de compromiso.

Dos mensajes tipo

  1. Cliente informado del estado de su sitio

    «Hola, leímos la versión PHP de su sitio el [fecha]. Era la [versión], anterior a la corrección publicada por el proyecto PHP para dos fallos críticos. La actualizamos el [fecha], sin interrupción prevista. Después le enviaremos la prueba fechada de la versión en servicio. No necesita hacer nada. Si tiene preguntas, responda a este mensaje.»

  2. Cliente cuyo sitio no puede migrarse enseguida

    «Hola, su sitio funciona con una versión de PHP que ya no recibe correcciones del proyecto. La migración requiere [trabajos], que le proponemos para el [fecha]. Mientras tanto, aplicamos [medida: paquete corregido por el proveedor, retirada del formulario de envío de archivos, filtrado]. Estas medidas reducen el riesgo sin eliminarlo. Confírmenos la fecha elegida antes del [fecha].»

Probar la corrección y repetir la auditoría

La prueba de una corrección es un registro por sitio: la medición antes, la intervención, la misma medición después, la captura o la salida del comando, el número de versión, la fecha y el nombre del operador. Repetir la misma medición con el mismo método es lo que hace comparable la prueba. Conserve el diario junto al registro.

Tenga presente el límite: una versión leída prueba la versión servida en el momento de la medición, no la ausencia de intrusión antes de la actualización. Si un sitio siguió expuesto después del 21 de octubre de 2026, la búsqueda de rastros de explotación es un segundo trabajo, descrito en el artículo sobre PHP2Shell.

La cadencia: una auditoría por trimestre y en cada desencadenante

Repita la auditoría cada trimestre, además de con cada nueva CVE crítica y cada fin de vida de rama. Compare las dos mediciones: una deriva es un sitio cuya versión ha bajado o cuyo nivel de confianza ha vuelto a presunto. Anote en el registro las fechas de fin de vida que importan. Para PHP 8.2, el proyecto indica el 31 de diciembre de 2026; la lista de comprobación de migración a 8.3 u 8.4 está en el artículo dedicado. El primer lote de la siguiente auditoría ya se conoce: todo lo que siga en 8.2 el 1 de enero.

La documentación oficial

  • Aviso de PHP del 21 de octubre de 2026 — https://www.php.net/archive/2026.php#2026-10-21-5
  • Versiones soportadas de PHP — https://www.php.net/supported-versions.php
  • Alerta de CISA del 26 de octubre de 2026 — https://www.cisa.gov/news-events/alerts/2026/10/26/cisa-adds-two-known-exploited-vulnerabilities-catalog
  • Repositorio php2shell de NCSC-NL — https://github.com/NCSC-NL/php2shell
  • Aviso de AlmaLinux sobre los paquetes corregidos — https://almalinux.org/blog/2026-10-21-php2shell-cve-2026-109618-cve-2026-109619/
  • MultiPHP Manager (cPanel) — https://docs.cpanel.net/cpanel/software/multiphp-manager-for-cpanel/
  • wp cli info — https://developer.wordpress.org/cli/commands/cli/info/

Un solo lugar para leer e imponer la versión PHP de cada cuenta

Cuando los sitios cliente están repartidos entre varios proveedores, cada auditoría parte de cero: accesos que reunir, versiones heterogéneas, renovaciones dispersas. Un alojamiento de revendedor Agency S (WHM, marca blanca) o una flota de VPS reúne las cuentas en un mismo sitio: una interfaz para leer la versión PHP de cada cuenta, imponerla y conservar la prueba. Los planes Agency incluyen copias de seguridad diarias.

¿Necesita ayuda?

Consulte nuestro centro de ayuda y nuestra FAQ, o contacte con nuestro equipo: llamada, WhatsApp o correo electrónico. Soporte en francés, inglés y árabe.

Escribir por WhatsAppse abre en una pestaña nueva