# php_admin_value: bloquear ajustes frente a la sobrescritura

> php_admin_value y php_admin_flag explicados: cómo bloquear valores de PHP en el pool de FPM y en Apache frente a ini_set(), .htaccess y .user.ini y comprobarlo.

Fuente: https://phpsos.de/es/blog/php-admin-value-sperren/  
Actualizado: 25/10/2026  
Proveedor: PHP SOS, Ayuda de emergencia para PHP y seguridad de servidores. Ayuda inmediata por WhatsApp: https://wa.me/491736494914?text=Hola%20PHP%20SOS%2C%20necesitamos%20ayuda%20con%20nuestro%20servidor%20PHP.%20Empresa%3A%20%E2%80%A6%20Sitio%20web%3A%20%E2%80%A6

**En resumen:** `php_admin_value` y `php_admin_flag` fijan ajustes de PHP en el pool de PHP-FPM o en la configuración de Apache de modo que las aplicaciones no puedan cambiarlos ni con `ini_set()` ni con `.htaccess`. php.net exige exactamente eso para las medidas transitorias de PHP2Shell, por ejemplo para `memory_limit=-1`. Tras fijarlos, el servicio debe reiniciarse y el valor debería comprobarse en el contexto web.

## Por qué «fijado» no significa «bloqueado»

En los días posteriores al 21 de octubre de 2026, muchos administradores escribieron en su php.ini las medidas transitorias de php.net. Un detalle de la recomendación pasó con frecuencia inadvertido: `memory_limit=-1` debe fijarse de modo que las aplicaciones no puedan sobrescribirlo. php.net cita para ello expresamente `php_admin_value` en el pool de FPM o en la configuración de Apache.

El motivo es sencillo. Muchos CMS, tiendas y frameworks fijan sus propios valores, por ejemplo un límite de memoria mayor para las importaciones. Si el valor figura solo en el php.ini, la aplicación lo sobrescribe en la siguiente llamada. La medida de protección existe entonces sobre el papel, pero no en el proceso en ejecución.

Esto no afecta solo a PHP2Shell. Todo refuerzo, desde las salidas de error desactivadas hasta los límites de subida, es tan fuerte como su nivel más débil.

## Quién puede cambiar ajustes de PHP

PHP conoce cuatro modos de modificación. Cada ajuste tiene uno, y este determina en qué lugares puede fijarse. Los significados proceden del manual de PHP.

| Modo | Dónde puede fijarse el valor | Ejemplos |
|---|---|---|
| `INI_USER` | en el script con `ini_set()` y en `.user.ini` | pocos valores de ejecución |
| `INI_PERDIR` | php.ini, `.htaccess`, `httpd.conf`, `.user.ini` | `post_max_size`, `session.upload_progress.enabled` |
| `INI_SYSTEM` | solo php.ini o `httpd.conf` | `file_uploads`, `disable_functions` |
| `INI_ALL` | en cualquier parte, también con `ini_set()` | `memory_limit`, `display_errors`, `open_basedir` |

Los más peligrosos son sobre todo los valores `INI_ALL`: pueden cambiarse desde cualquier script. Los valores `INI_PERDIR` no pueden cambiarse con `ini_set()`, pero sí mediante un `.htaccess` con mod_php o un `.user.ini` con PHP-FPM. Quien tiene derechos de escritura en el webroot, y por tanto también el código inyectado, puede crear esos archivos.

## php_admin_value en el pool de FPM y en Apache

En PHP-FPM, los valores figuran en el archivo del pool. El manual de PHP lo establece así: los valores fijados con `php_admin_value` y `php_admin_flag` no pueden sobrescribirse con `ini_set()`. Para los valores de activado y desactivado use `php_admin_flag`; para todos los demás, `php_admin_value`.

```ini
; /etc/php/8.3/fpm/pool.d/seite1.conf (extracto)
[seite1]
user = seite1
group = seite1
listen = /run/php/seite1.sock

php_admin_value[memory_limit] = -1
php_admin_value[post_max_size] = 32M
php_admin_value[upload_max_filesize] = 24M
php_admin_flag[session.upload_progress.enabled] = off
php_admin_flag[display_errors] = off
php_admin_value[error_log] = /var/log/php/seite1-fehler.log
php_admin_value[open_basedir] = /var/www/seite1/:/tmp/seite1/
```

Según php.net, `memory_limit=-1` solo pertenece a la configuración junto con un límite de memoria mediante contenedor o cgroup. Cómo se logra con systemd figura en el artículo [Fijar límites de memoria con systemd y cgroups](https://phpsos.de/es/blog/speichergrenzen-systemd-cgroups/).

En Apache con mod_php, las directivas pertenecen a la configuración del servidor o al VirtualHost. Según el manual de PHP, no están permitidas en `.htaccess` y, una vez fijadas, ni `.htaccess` ni `ini_set()` pueden cambiarlas.

```apache
<VirtualHost *:443>
    ServerName www.example.de
    DocumentRoot /var/www/seite1/public
    <IfModule php_module>
        php_admin_value memory_limit -1
        php_admin_value post_max_size 32M
        php_admin_value upload_max_filesize 24M
        php_admin_flag session.upload_progress.enabled off
        php_admin_flag display_errors off
    </IfModule>
</VirtualHost>
```

Dos sutilezas del manual: para borrar un valor fijado previamente, use `none` como valor. Y las constantes de PHP como `E_ALL` no tienen significado en la configuración de Apache; para `error_reporting` debe indicar allí el valor numérico.

## Qué valores conviene bloquear

No todo ajuste tiene que estar bloqueado. Tiene sentido para todo lo que afecta a la seguridad o sirve como medida transitoria:

1. Los valores transitorios de PHP2Shell de php.net: `memory_limit`, `post_max_size`, `upload_max_filesize`, `session.upload_progress.enabled` y, en PHP 8.5, `fatal_error_backtraces`.
2. Salida de errores y registro: `display_errors`, `display_startup_errors`, `log_errors`, `error_log`.
3. Acceso a archivos y aislamiento: `open_basedir`, `upload_tmp_dir`, `session.save_path`.
4. Accesos de red desde PHP: `allow_url_include` y, si la aplicación no lo necesita, `allow_url_fopen`.
5. Funciones bloqueadas mediante `disable_functions`, que en el pool, según el manual, complementan la lista del php.ini y no la sustituyen. Detalles en la guía [Usar bien disable_functions](https://phpsos.de/es/ratgeber/disable-functions/).

Con `session.upload_progress.enabled`, el bloqueo es especialmente importante, porque de lo contrario el valor podría volver a activarse mediante un `.user.ini`. Más información en [Desactivar session.upload_progress: bien y de forma permanente](https://phpsos.de/es/blog/session-upload-progress-abschalten/).

## Comprobar que el bloqueo funciona

Tras cada cambio, reinicie el servicio y compruebe el valor en el contexto web. Un breve archivo de prueba, borrado de inmediato, muestra si el pool mantiene el valor incluso cuando la aplicación quiere cambiarlo:

```php
<?php
// Archivo de prueba: colóquelo un momento, llámelo una vez a través del dominio y bórrelo de inmediato
header('Content-Type: text/plain');
$vorher = ini_get('memory_limit');
$versuch = @ini_set('memory_limit', '256M');
echo "memory_limit: $vorher\n";
echo 'Änderung per ini_set() ', ($versuch === false ? 'blockiert' : 'MÖGLICH'), "\n";
```

Se espera `-1` y «blockiert» (bloqueado). Si la salida dice «MÖGLICH» (posible), el valor no está fijado mediante `php_admin_value` o el servicio todavía no se ha reiniciado. Repita la comprobación para cada pool y cada versión de PHP.

> **Consejo:**
> Registre los valores bloqueados de forma centralizada, por ejemplo en una plantilla de pool o en su gestión de configuración. Los paneles de hosting a veces sobrescriben los archivos de pool modificados a mano en el siguiente guardado; allí los valores pertenecen a los campos previstos por el panel.

Cómo ordena PHP en conjunto sus niveles de configuración lo explica [El php.ini explicado: estructura, niveles y precedencia](https://phpsos.de/es/php/php-ini-erklaert/). Las medidas transitorias completas figuran en [Medidas inmediatas si todavía no puede parchear](https://phpsos.de/es/php2shell/sofortmassnahmen-ohne-patch/).

## Conclusión: solo lo bloqueado está realmente fijado

Las medidas transitorias de php.net para PHP2Shell han hecho patente una distinción que antes se pasaba a menudo por alto: un valor en el php.ini es, para muchos ajustes, solo una sugerencia; un valor en `php_admin_value` es una norma. Para valores de comodidad como la zona horaria, la diferencia es irrelevante. Para ajustes de seguridad y medidas transitorias, decide si la medida surte efecto en el funcionamiento real.

El esfuerzo es manejable: un puñado de líneas por pool o VirtualHost, un reinicio, una breve comprobación. Mantenga la lista de valores bloqueados pequeña y justificada, para que los desarrolladores entiendan por qué su aplicación no puede cambiar un valor. Y mantenga la lista en sus plantillas, para que los sitios web nuevos la hereden automáticamente.

## ¿Cómo ayuda PHP SOS en concreto?

- **Leer los niveles:** averiguamos para cada sitio web qué valores rigen realmente desde php.ini, pool, Apache, `.htaccess` o `.user.ini`.
- **Fijar los bloqueos:** registramos los valores relevantes para la seguridad y las medidas transitorias de PHP2Shell como `php_admin_value` o `php_admin_flag` y reiniciamos los servicios.
- **Probar la aplicación:** comprobamos que la aplicación funciona sin errores con los valores bloqueados y analizamos el log de errores.
- **Mantener las plantillas:** en el marco del [refuerzo de servidores](https://phpsos.de/es/leistungen/server-haertung/) incorporamos los valores a plantillas de pool y documentación.


## Preguntas frecuentes

**¿Cuál es la diferencia entre php_value y php_admin_value?**  
Ambos fijan un ajuste de PHP. Los valores de php_value puede volver a cambiarlos la aplicación más tarde, por ejemplo con ini_set() o .htaccess. Los valores de php_admin_value y php_admin_flag están, según el manual de PHP, bloqueados para ini_set() y, en Apache, también para .htaccess.

**¿Puedo escribir php_admin_value en un archivo .htaccess?**  
No. Según el manual de PHP, php_admin_value no está permitido en archivos .htaccess. Pertenece a la configuración del servidor Apache o al VirtualHost y, en PHP-FPM, al archivo del pool.

**¿Qué ocurre si una aplicación intenta cambiar un valor bloqueado?**  
La llamada a ini_set() falla y devuelve false; el valor bloqueado se mantiene. Las aplicaciones bien programadas lo gestionan sin problema. Aun así, tras el cambio revise el log de errores y las funciones más importantes.

**¿Tengo que reiniciar tras un cambio en el pool?**  
Sí. PHP-FPM lee los archivos de pool al arrancar o al recargar el servicio. En Apache con mod_php vale lo mismo para la configuración del servidor. Sin reinicio sigue en uso el valor antiguo.

**¿Se puede ampliar disable_functions en el pool?**  
Sí, con una particularidad: según el manual de PHP, disable_functions en el pool de FPM no sobrescribe los valores del php.ini, sino que los complementa. El pool puede, por tanto, bloquear más funciones, pero no liberar ninguna.

## Fuentes

- [Manual de PHP: configuración de FPM](https://www.php.net/manual/en/install.fpm.configuration.php)
- [Manual de PHP: modificar la configuración](https://www.php.net/manual/en/configuration.changes.php)
- [Manual de PHP: modos de modificación de los ajustes](https://www.php.net/manual/en/configuration.changes.modes.php)
- [php.net: avisos de seguridad](https://www.php.net/)
