En resumen: un archivo que solo llama a phpinfo() muestra a cualquier visitante la versión, los módulos, las rutas y los ajustes de PHP, y a menudo también variables de entorno con credenciales. Para la seguridad de phpinfo rige, por tanto: no dejar nunca estos archivos de forma permanente en el webroot, borrarlos tras usarlos y comprobar el estado de PHP mejor mediante la gestión de paquetes y la configuración. En cualquier caso, una salida de phpinfo no acredita el estado del parche frente a PHP2Shell.
El archivo de prueba que se queda
Desde el 21 de octubre de 2026, miles de administradores comprueban qué versión de PHP sirven sus sitios web. El camino más rápido es conocido: crear un archivo info.php con una sola línea, abrirlo en el navegador y leer el resultado. Funciona. El problema empieza después, cuando el archivo se olvida.
Estos archivos sobreviven sorprendentemente mucho. Se trasladan con las mudanzas, acaban en copias de seguridad y aparecen al cabo de años en directorios que ya nadie conoce. Los escáneres automatizados consultan constantemente nombres de archivo típicos. Lo que para el administrador era una ayuda es, para un atacante, un plano del servidor.
Están especialmente afectadas las agencias y los proveedores de hosting con muchos sitios de clientes. Quien en una semana frenética revisa decenas de sitios web crea enseguida decenas de archivos de prueba. Basta una sola carpeta olvidada para que el archivo siga siendo accesible meses después.
Qué revela phpinfo() y por qué importa para la seguridad
Según el manual de PHP, phpinfo() muestra el estado actual de PHP. Mediante constantes puede controlarse qué partes aparecen; sin indicación, es todo.
| Ámbito (constante) | Contenido según el manual | Por qué es delicado |
|---|---|---|
INFO_GENERAL |
Compilación, ubicación del php.ini, servidor web, sistema | Revela el sistema operativo y las rutas |
INFO_CONFIGURATION |
Valores locales y maestros de todas las directivas | Muestra si disable_functions o open_basedir están activas |
INFO_MODULES |
Extensiones cargadas con sus ajustes | Los atacantes ven qué funciones están disponibles |
INFO_ENVIRONMENT |
Variables de entorno | Aquí suelen estar las credenciales de bases de datos o de API |
INFO_VARIABLES |
Variables predefinidas (Environment, GET, POST, Cookie, Server) | Contiene cabeceras y cookies de la petición actual |
Lo más peligroso son las dos últimas filas. Las aplicaciones modernas cargan gustosamente las credenciales desde variables de entorno, por ejemplo desde un archivo .env o desde la configuración del contenedor. Esos valores aparecen entonces en texto claro en la salida. Cómo proteger en general esos secretos lo describe el artículo Proteger correctamente las credenciales y los archivos .env.
A ello se suma que la salida muestra los valores de la petición en curso, es decir, también cookies y cabeceras. Si un atacante puede dirigir a un visitante a la página y leer la respuesta, por ejemplo mediante una vulnerabilidad de cross-site scripting en otro lugar, quedan visibles incluso las cookies marcadas como HttpOnly.
Por qué phpinfo no es una prueba frente a PHP2Shell
Muchos han creado el archivo justamente para comprobar el estado del parche. Para eso solo sirve de forma limitada. Las distribuciones y los proveedores de hosting suelen aplicar las correcciones como backport; según informes, por ejemplo Ubuntu 24.04 sigue mostrando 8.3.6 tras la actualización. El número mostrado dice, pues, poco. A la inversa, un número actual no demuestra que se hayan reiniciado todos los workers.
Es fiable el estado del paquete con los números CVE en el changelog, complementado con el reinicio de todos los procesos de PHP. Cómo hacerlo lo explica el artículo Comprobar correctamente la versión de PHP y el estado del parche.
Una salida momentánea en el contexto web tiene, aun así, su lugar: muestra qué php.ini y qué valores rigen realmente para el sitio web, porque la línea de comandos suele leer otra configuración. Los antecedentes sobre niveles y prioridad los explica El php.ini explicado. Si lo necesita, hágalo con protección de acceso, con un nombre de archivo aleatorio y solo durante minutos.
Para la mayoría de las preguntas hay de todos modos mejores vías. La versión de PHP de un pool de FPM consta en su configuración y en la lista de procesos. Valores individuales pueden consultarse con un script fuera del webroot mediante ini_get(), sin revelarlo todo. Y en los paneles de hosting, la interfaz muestra la versión asignada a cada sitio web, aunque sin información sobre backports.
Encontrar archivos olvidados: pasos de comprobación concretos
Así se localizan los restos en un servidor Linux. Los comandos solo leen y no modifican nada.
- Buscar archivos con llamada a phpinfo (adapte la ruta):
grep -rlE "phpinfo[[:space:]]*\(" /var/www --include="*.php" 2>/dev/null
- Comprobar nombres de archivo típicos, también sin coincidencias en el contenido:
find /var/www -type f \( -iname "info.php" -o -iname "phpinfo.php" -o -iname "test.php" -o -iname "i.php" \) 2>/dev/null
-
Valorar los resultados: no todo hallazgo es un archivo de prueba. Herramientas de administración, paneles o frameworks pueden usar
phpinfo()tras un inicio de sesión. Lo decisivo es si el archivo es accesible desde internet sin autenticación. -
Revisar los accesos en el log antes de borrar:
grep -E "GET /(info|phpinfo|test|i)\.php" /var/log/nginx/access.log* 2>/dev/null | tail -n 50
- Borrar y sustituir los secretos: si en la salida figuraba una contraseña o una clave y el archivo era público, el valor se considera conocido. Cámbielo.
Un hallazgo con fecha de creación desconocida y un contenido llamativo junto a la llamada a phpinfo puede ser también una puerta trasera. Entonces no se debe solo borrar, sino asegurar y hacer revisar; véase Reconocer y eliminar webshells.
Prevenir de forma duradera en lugar de limpiar
Tres medidas evitan que el tema vuelva. Primera: incluir phpinfo en la lista disable_functions del php.ini para el contexto web. Compruebe antes si su panel necesita la función para una página de estado. Cómo actúa el ajuste y dónde están sus límites figura en Usar bien disable_functions.
; php.ini para FPM o Apache, después reiniciar todos los procesos de PHP
disable_functions = phpinfo
expose_php = Off
Segunda: despliegue solo mediante un proceso fijo, por ejemplo con Git o una pipeline de build, para que no lleguen al webroot archivos sueltos a mano. Tercera: la información de estado pertenece a la monitorización o al inventario, no a una página pública.
expose_php = Off elimina además la cabecera con la que PHP comunica su versión en cada respuesta. Eso no sustituye a una actualización, pero quita a los escáneres automatizados una información cómoda. Quien tenga a varias personas con acceso al servidor debería además acordar una regla sencilla: los archivos de prueba se borran en el mismo paso de trabajo en que se crearon, y no «más tarde».
¿Cómo ayuda PHP SOS en concreto?
- Examinamos sus webroots en busca de archivos phpinfo, scripts de prueba y otros restos y valoramos cada hallazgo.
- Analizamos los accesos a los archivos encontrados y le indicamos qué secretos debería sustituir.
- Acreditamos el estado del parche frente a PHP2Shell mediante el changelog del paquete y el inicio de los procesos, en lugar de una indicación de versión.
- Aplicamos
disable_functions,expose_phpy otros refuerzos de forma duradera en el marco del refuerzo del servidor.
Conclusión: un archivo phpinfo se crea en segundos y se olvida igual de rápido. Quien lo busca y lo elimina ahora cierra una fuga de datos innecesaria y se apoya, para el estado del parche, en evidencias fiables.
Preguntas frecuentes
¿Es un archivo phpinfo una vulnerabilidad en sí mismo?
No abre ningún acceso, pero proporciona a los atacantes una descripción detallada del servidor: versión, módulos, rutas, ajustes y, según el entorno, también variables de entorno. Eso facilita ataques dirigidos y puede dejar al descubierto credenciales.
¿Demuestra el número de versión de phpinfo que PHP2Shell está parcheado?
No. Las distribuciones y los proveedores de hosting suelen aplicar las correcciones como backport, y el número mostrado se mantiene igual. El estado del parche lo acreditan el changelog del paquete y la confirmación del proveedor, además del reinicio de todos los procesos de PHP.
¿Qué hacer si un archivo phpinfo estuvo público durante mucho tiempo?
Borrar el archivo, revisar en el log de acceso quién lo descargó y sustituir todos los secretos que aparecían en la salida, por ejemplo contraseñas de bases de datos o claves de API procedentes de variables de entorno.
¿Puedo desactivar phpinfo() por completo?
Sí, mediante disable_functions en el php.ini del contexto web. Compruebe antes si un panel o una aplicación usa la función para páginas de estado y reinicie después los procesos de PHP.