# php_admin_value: bloquear definições contra a sobrescrita

> php_admin_value e php_admin_flag explicados: como bloquear valores do PHP no pool FPM e no Apache contra ini_set(), .htaccess e .user.ini e como o verificar.

Fonte: https://phpsos.de/pt/blog/php-admin-value-sperren/  
Atualizado em: 25/10/2026  
Prestador: PHP SOS, Assistência de emergência PHP e segurança de servidores. Ajuda imediata por WhatsApp: https://wa.me/491736494914?text=Ol%C3%A1%2C%20PHP%20SOS%2C%20precisamos%20de%20ajuda%20com%20o%20nosso%20servidor%20PHP.%20Empresa%3A%20%E2%80%A6%20Site%3A%20%E2%80%A6

**Em resumo:** `php_admin_value` e `php_admin_flag` definem configurações do PHP no pool PHP-FPM ou na configuração do Apache de modo que as aplicações não as possam alterar nem com `ini_set()` nem com `.htaccess`. O php.net exige precisamente isso para as medidas transitórias do PHP2Shell, por exemplo para `memory_limit=-1`. Depois de definir, o serviço tem de ser reiniciado e o valor deve ser verificado no contexto web.

## Por que «definido» não significa «bloqueado»

Nos dias após 21 de outubro de 2026, muitos administradores escreveram as medidas transitórias do php.net no seu php.ini. Um pormenor da recomendação passou muitas vezes despercebido: `memory_limit=-1` deve ser definido de modo que as aplicações não o possam sobrescrever. O php.net indica para isso expressamente `php_admin_value` no pool FPM ou na configuração do Apache.

A razão é simples. Muitos CMS, lojas e frameworks definem os seus próprios valores, por exemplo um limite de memória mais alto para importações. Se o valor estiver apenas no php.ini, a aplicação sobrescreve-o na chamada seguinte. A medida de proteção existe então no papel, mas não no processo em execução.

Isto não afeta apenas o PHP2Shell. Qualquer reforço, desde saídas de erro desativadas a limites de upload, é tão forte quanto o seu nível mais fraco.

## Quem pode alterar as definições do PHP

O PHP conhece quatro modos de alteração. Cada definição tem um deles, que determina em que locais pode ser definida. Os significados provêm do manual do PHP.

| Modo | Onde o valor pode ser definido | Exemplos |
|---|---|---|
| `INI_USER` | no script com `ini_set()` e em `.user.ini` | poucos valores de tempo de execução |
| `INI_PERDIR` | php.ini, `.htaccess`, `httpd.conf`, `.user.ini` | `post_max_size`, `session.upload_progress.enabled` |
| `INI_SYSTEM` | apenas php.ini ou `httpd.conf` | `file_uploads`, `disable_functions` |
| `INI_ALL` | em qualquer lado, também com `ini_set()` | `memory_limit`, `display_errors`, `open_basedir` |

Os valores `INI_ALL` são os mais perigosos: podem ser alterados a partir de qualquer script. Os valores `INI_PERDIR` não podem ser alterados com `ini_set()`, mas sim através de um `.htaccess` com mod_php ou de um `.user.ini` com PHP-FPM. Quem tem direitos de escrita na raiz web, ou seja, também o código introduzido, pode criar esses ficheiros.

## php_admin_value no pool FPM e no Apache

No PHP-FPM, os valores estão no ficheiro do pool. O manual do PHP estabelece: os valores definidos com `php_admin_value` e `php_admin_flag` não podem ser sobrescritos com `ini_set()`. Para valores de ligar e desligar use `php_admin_flag`, para todos os outros `php_admin_value`.

```ini
; /etc/php/8.3/fpm/pool.d/seite1.conf (excerto)
[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/
```

Segundo o php.net, o `memory_limit=-1` só pertence à configuração juntamente com um limite de memória através de contentor ou cgroup. Como isso se consegue com o systemd está no artigo [Definir limites de memória com systemd e cgroups](https://phpsos.de/pt/blog/speichergrenzen-systemd-cgroups/).

No Apache com mod_php, as diretivas pertencem à configuração do servidor ou ao VirtualHost. Segundo o manual do PHP, não são permitidas em `.htaccess` e, uma vez definidas, nem o `.htaccess` nem o `ini_set()` as podem alterar.

```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>
```

Duas subtilezas do manual: para apagar um valor definido anteriormente, use `none` como valor. E as constantes do PHP como `E_ALL` não têm significado na configuração do Apache; para `error_reporting`, tem de indicar aí o valor numérico.

## Que valores deve bloquear

Nem todas as definições têm de estar bloqueadas. Faz sentido para tudo o que diz respeito à segurança ou serve como medida transitória:

1. Os valores transitórios do PHP2Shell do php.net: `memory_limit`, `post_max_size`, `upload_max_filesize`, `session.upload_progress.enabled` e, no PHP 8.5, `fatal_error_backtraces`.
2. Saída de erros e registo: `display_errors`, `display_startup_errors`, `log_errors`, `error_log`.
3. Acesso a ficheiros e isolamento: `open_basedir`, `upload_tmp_dir`, `session.save_path`.
4. Acessos de rede a partir do PHP: `allow_url_include` e, se a aplicação não precisar, `allow_url_fopen`.
5. Funções bloqueadas através de `disable_functions`, que no pool, segundo o manual, complementam a lista do php.ini e não a substituem. Pormenores no guia [Usar corretamente o disable_functions](https://phpsos.de/pt/ratgeber/disable-functions/).

No caso do `session.upload_progress.enabled`, o bloqueio é particularmente importante, porque o valor poderia, caso contrário, ser reativado através de um `.user.ini`. Mais informação em [Desativar o session.upload_progress: de forma correta e duradoura](https://phpsos.de/pt/blog/session-upload-progress-abschalten/).

## Verificar se o bloqueio funciona

Após cada alteração, reinicie o serviço e verifique o valor no contexto web. Um ficheiro de teste breve, eliminado logo a seguir, mostra se o pool mantém o valor mesmo quando a aplicação o quer alterar:

```php
<?php
// Ficheiro de teste: colocar por pouco tempo, abrir uma vez através do domínio, apagar de imediato
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";
```

Espera-se `-1` e «blockiert». Se a saída for «MÖGLICH», o valor não está definido através de `php_admin_value` ou o serviço ainda não foi reiniciado. Repita a verificação para cada pool e cada versão do PHP.

> **Dica:**
> Mantenha os valores bloqueados registados de forma centralizada, por exemplo num modelo de pool ou na sua gestão de configuração. Os painéis de alojamento sobrescrevem por vezes, na gravação seguinte, ficheiros de pool alterados à mão; aí os valores pertencem aos campos previstos pelo painel.

Como o PHP ordena, no seu conjunto, os níveis de configuração é explicado em [O php.ini explicado: estrutura, níveis e precedência](https://phpsos.de/pt/php/php-ini-erklaert/). As medidas transitórias completas estão em [Medidas imediatas, quando ainda não pode aplicar o patch](https://phpsos.de/pt/php2shell/sofortmassnahmen-ohne-patch/).

## Conclusão: só bloqueado está realmente definido

As medidas transitórias do php.net para o PHP2Shell trouxeram à consciência uma distinção que antes passava muitas vezes despercebida: para muitas definições, um valor no php.ini é apenas uma sugestão, um valor em `php_admin_value` é uma imposição. Para valores de conforto, como o fuso horário, a diferença é irrelevante. Para definições de segurança e medidas transitórias, decide se a medida chega sequer a atuar na operação.

O esforço é reduzido: um punhado de linhas por pool ou VirtualHost, um reinício, uma breve verificação. Mantenha a lista dos valores bloqueados curta e fundamentada, para que os programadores possam perceber por que razão a sua aplicação não pode alterar um valor. E mantenha a lista nos seus modelos, para que os novos sites a herdem automaticamente.

## Como ajuda concretamente a PHP SOS?

- **Ler os níveis:** determinamos, para cada site, que valores do php.ini, do pool, do Apache, do `.htaccess` ou do `.user.ini` se aplicam efetivamente.
- **Definir bloqueios:** registamos os valores relevantes para a segurança e as medidas transitórias do PHP2Shell como `php_admin_value` ou `php_admin_flag` e reiniciamos os serviços.
- **Testar a aplicação:** verificamos se a aplicação corre sem erros com os valores bloqueados e analisamos o registo de erros.
- **Manter modelos:** no âmbito do [reforço de segurança de servidores](https://phpsos.de/pt/leistungen/server-haertung/), incorporamos os valores em modelos de pool e na documentação.


## Perguntas frequentes

**Qual é a diferença entre php_value e php_admin_value?**  
Ambos definem uma configuração do PHP. Os valores de php_value podem ser alterados mais tarde pela aplicação, por exemplo com ini_set() ou .htaccess. Segundo o manual do PHP, os valores de php_admin_value e php_admin_flag estão bloqueados para o ini_set() e, no Apache, também para o .htaccess.

**Posso escrever php_admin_value num ficheiro .htaccess?**  
Não. Segundo o manual do PHP, o php_admin_value não é permitido em ficheiros .htaccess. Pertence à configuração do servidor Apache ou ao VirtualHost e, no PHP-FPM, ao ficheiro do pool.

**O que acontece se uma aplicação quiser alterar um valor bloqueado?**  
A chamada ao ini_set() falha e devolve false; o valor bloqueado mantém-se. As aplicações bem programadas lidam com isso. Ainda assim, após a alteração, verifique o registo de erros e as funções mais importantes.

**Tenho de reiniciar após uma alteração no pool?**  
Sim. O PHP-FPM lê os ficheiros do pool no arranque ou ao recarregar o serviço. No Apache com mod_php, o mesmo se aplica à configuração do servidor. Sem reinício, o valor antigo continua a correr.

**É possível alargar o disable_functions no pool?**  
Sim, com uma particularidade: segundo o manual do PHP, o disable_functions no pool FPM não sobrescreve os valores do php.ini, mas complementa-os. O pool pode, portanto, bloquear mais funções, mas não libertar nenhuma.

## Fontes

- [Manual do PHP: configuração do FPM](https://www.php.net/manual/en/install.fpm.configuration.php)
- [Manual do PHP: alterar a configuração](https://www.php.net/manual/en/configuration.changes.php)
- [Manual do PHP: modos de alteração das definições](https://www.php.net/manual/en/configuration.changes.modes.php)
- [php.net: comunicados de segurança](https://www.php.net/)
