En resumen: para la seguridad de php.ini cuentan sobre todo cuatro ámbitos: no mostrar mensajes de error hacia fuera, cookies de sesión seguras, subidas limitadas y valores bloqueados que las aplicaciones no puedan sobrescribir. Tras PHP2Shell se añaden las medidas transitorias de php.net, sobre todo session.upload_progress.enabled=0. Una configuración segura, sin embargo, nunca sustituye a la actualización.
Por qué php.ini vuelve a estar en el punto de mira tras PHP2Shell
php.ini es el archivo central de configuración de PHP. En muchos servidores se configuró una vez y después apenas se ha tocado. Con PHP2Shell eso ha cambiado: para las dos vulnerabilidades CVE-2026-109618 y CVE-2026-109619, php.net indica medidas transitorias que actúan justo aquí.
Las vulnerabilidades en sí residen en el intérprete de PHP. Están corregidas en PHP 8.5.12, 8.4.27, 8.3.36 y 8.2.35, publicadas el 21/10/2026. Una buena configuración ayuda de todos modos de dos maneras: puede dificultar la explotación y limita el daño si alguna vez algo se cuela.
Además, muchos responsables no saben exactamente qué ajustes rigen en su servidor. Ese es el primer paso.
¿Qué php.ini rige en su servidor?
Según el modo de ejecución, PHP puede leer distintos archivos de configuración. La línea de comandos, PHP-FPM y Apache con mod_php tienen, por ejemplo en Debian y Ubuntu, sus propias carpetas bajo /etc/php/<version>/. Quien solo cambia el archivo de la CLI no cambia nada en el sitio web.
# Archivos de configuración de la línea de comandos
php --ini
# Configuración de PHP-FPM (adapte el número de versión)
php-fpm8.3 -i | grep -E "Loaded Configuration|Scan this dir"
# Comprobar valores individuales de PHP-FPM
php-fpm8.3 -i | grep -E "^(expose_php|display_errors|session.upload_progress.enabled) "
Además, los valores pueden estar en el pool de FPM, en la configuración de Apache, en .htaccess (solo mod_php) o en .user.ini (FPM y CGI). Qué versión se ejecuta realmente en el servidor y si incluye un backport lo aclara el artículo Cómo comprobar bien la versión de PHP y el estado del parche.
Ajustes básicos para más seguridad en php.ini
Los valores siguientes son razonables para la mayoría de los servidores de producción. Antes de usarlos, compruebe en un entorno de pruebas que su aplicación funciona bien con todos ellos.
; Sin indicar la versión en la cabecera HTTP
expose_php = Off
; Registrar los errores, pero nunca mostrarlos en el navegador
display_errors = Off
display_startup_errors = Off
log_errors = On
error_log = /var/log/php/error.log
; No incluir archivos desde direcciones remotas
allow_url_include = Off
; Dejar allow_url_fopen activo solo si la aplicación lo necesita
allow_url_fopen = Off
; Sesiones: estrictas, solo por HTTPS, no legibles con JavaScript
session.use_strict_mode = 1
session.use_only_cookies = 1
session.cookie_secure = 1
session.cookie_httponly = 1
session.cookie_samesite = Lax
; Limitar el tiempo de ejecución y las entradas
max_execution_time = 30
max_input_time = 60
max_input_vars = 1000
Algunas aplicaciones necesitan allow_url_fopen para actualizaciones o interfaces. Desactívelo solo si lo ha comprobado antes. Las funciones que ejecutan comandos del sistema se pueden bloquear además; cómo hacerlo sin efectos secundarios lo explica la guía Usar disable_functions correctamente.
Medidas transitorias de php.net contra PHP2Shell
Si no puede aplicar el parche de inmediato, php.net indica varios ajustes que reducen el riesgo. Expresamente no son una protección completa, sino un puente hasta la actualización.
; Desactivar el progreso de subida de sesión (también por CVE-2026-115560)
session.upload_progress.enabled = 0
; Limitar el tamaño de la petición: 8M sin subidas, 32M con subidas
post_max_size = 8M
upload_max_filesize = 6M
; Solo PHP 8.5: sin backtraces en errores graves
fatal_error_backtraces = 0
Además, php.net recomienda establecer memory_limit=-1 de modo que las aplicaciones no puedan sobrescribir el valor, y fijar el límite de memoria mediante el contenedor o cgroup, no mediante RLIMIT_AS ni RLIMIT_DATA. Esta medida va en el pool de FPM o en la configuración del servidor y debería combinarse con un límite de cgroup que funcione. Encontrará la visión de conjunto completa en Medidas inmediatas si todavía no puede aplicar el parche.
session.upload_progress.enabled=0 solo surte efecto desde php.ini, el pool de FPM o la configuración del servidor. Si se establece mediante ini_set() o .user.ini, la medida no funciona. Después, reinicie todos los workers.
Bloquear valores frente a la sobrescritura
Muchas aplicaciones establecen valores propios, por ejemplo para memoria o subidas. Con php_admin_value y php_admin_flag fija los ajustes de modo que ni ini_set() ni .user.ini puedan cambiarlos. En el pool de FPM se ve así:
; /etc/php/8.3/fpm/pool.d/meine-seite.conf (extracto)
php_admin_flag[display_errors] = off
php_admin_flag[session.upload_progress.enabled] = off
php_admin_value[memory_limit] = -1
php_admin_value[post_max_size] = 8M
php_admin_value[upload_max_filesize] = 6M
php_admin_value[error_log] = /var/log/php/meine-seite.error.log
En Apache con mod_php rige la misma lógica con php_admin_value y php_admin_flag en la configuración del VirtualHost. Después, recargue el servicio y contraste el valor activo:
sudo systemctl reload php8.3-fpm
# Hora de inicio de los procesos: ¿es posterior al cambio?
ps -eo pid,lstart,cmd | grep "[p]hp-fpm"
Una recarga reinicia los workers de PHP-FPM. Tras una actualización de PHP, en cambio, es necesario un reinicio completo de todos los procesos de PHP para que no siga ejecutándose ningún proceso antiguo en memoria. Si hay varios sitios web en un servidor, además merece la pena tener un pool propio para cada uno; más información en la guía open_basedir y aislamiento por sitio web.
Errores frecuentes y una breve lista de comprobación
La mayoría de los problemas con php.ini no se deben a valores erróneos, sino a valores en el lugar equivocado. Lo típico es modificar el archivo de la CLI mientras el sitio web se ejecuta con PHP-FPM. Igual de frecuente es que, tras un cambio, falte el reinicio, o que un panel de hosting sobrescriba el ajuste propio en el siguiente guardado.
Un segundo clásico son los mensajes de error visibles en el sitio web en producción. Revelan rutas, nombres de bases de datos o versiones y facilitan la orientación a los atacantes. Precisamente tras una migración o una reinstalación, display_errors suele volver a estar en On.
Estos puntos conviene controlarlos después de cada cambio y de cada actualización de PHP:
- ¿Qué archivo de configuración lee el modo de ejecución web y contiene sus valores?
- ¿Están desactivados
display_errorsyexpose_phpy se puede escribir en el registro de errores? - ¿Está
session.upload_progress.enableden0, establecido mediante php.ini o el pool? - ¿Están limitados los tamaños de subida y de petición de forma adecuada a la aplicación?
- ¿Tienen todos los procesos de PHP una hora de inicio posterior al último cambio?
Deje constancia del resultado con la fecha. Así podrá demostrar más adelante qué ajuste regía en cada momento.
¿Cómo ayuda PHP SOS en concreto?
- Averiguamos qué configuración está realmente activa en cada modo de ejecución.
- Aplicamos una configuración básica acordada y las medidas transitorias contra PHP2Shell, probadas con su aplicación.
- Bloqueamos los valores relevantes para la seguridad frente a sobrescrituras y reiniciamos todos los workers de forma controlada.
- Documentamos los ajustes y el resultado de la comprobación para que los cambios posteriores sigan siendo trazables.
Cómo es una protección duradera lo describe el servicio Refuerzo de servidores PHP.
Preguntas frecuentes
¿Qué php.ini usa realmente mi servidor web?
A menudo no es la misma que en la línea de comandos. PHP-FPM, Apache con mod_php y la CLI suelen tener sus propias carpetas de configuración. Compruebe por eso el archivo activo según el modo de ejecución, por ejemplo con php-fpm -i o con un archivo de prueba colocado un momento.
¿Sustituye una php.ini segura a la actualización de PHP?
No. Los ajustes reducen la superficie de ataque y dificultan la explotación, pero no cierran ninguna vulnerabilidad del intérprete de PHP. Las medidas transitorias de php.net sobre PHP2Shell tampoco son, expresamente, una protección completa.
¿Cuál es la diferencia entre php_value y php_admin_value?
Los valores establecidos con php_value pueden ser modificados de nuevo por la aplicación en tiempo de ejecución. Los valores definidos con php_admin_value en el pool de FPM o en la configuración de Apache, en cambio, quedan bloqueados para la aplicación, también frente a ini_set() y .user.ini.
¿Tengo que reiniciar tras cambiar php.ini?
Sí. PHP-FPM y Apache con mod_php solo leen la configuración al arrancar. Los valores nuevos solo se aplican después de reiniciar o recargar todos los servicios afectados.