# Desativar o session.upload_progress: de forma correta e duradoura

> Definir session.upload_progress.enabled=0 corretamente: onde o valor atua, como o bloquear contra reativação e como verificá-lo com segurança no contexto web.

Fonte: https://phpsos.de/pt/blog/session-upload-progress-abschalten/  
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:** Defina `session.upload_progress.enabled=0` no php.ini, no pool PHP-FPM ou na configuração do servidor Apache, nunca com `ini_set()` nem em `.user.ini`, e reinicie depois todos os workers PHP. A medida só se torna duradoura quando o valor está bloqueado contra reativação, se aplica em todos os modos de operação e em todas as versões do PHP instaladas e é verificada de novo após as atualizações.

## Uma definição pequena com efeito duplo

Raramente uma única definição do PHP recebeu tanta atenção. Quando o php.net publicou, a 21 de outubro de 2026, os patches contra o PHP2Shell, `session.upload_progress.enabled=0` constava da lista de medidas transitórias. Dois dias depois, seguiu-se o aviso sobre a CVE-2026-115560, e a solução recomendada era a mesma definição.

Muitos administradores definiram-na depressa nesses dias. Se atua em todo o lado é outra questão. As lacunas típicas enumeram-se depressa: o valor está apenas na configuração da CLI, esqueceu-se uma segunda versão do PHP ou um painel de alojamento sobrescreveu o ficheiro na gravação seguinte. Este artigo mostra como aplicar a medida de modo que continue a valer daqui a três meses.

Importante à partida: desativar não substitui a atualização do PHP. Segundo relatórios especializados, só `session.upload_progress.enabled=0` não fecha as duas vulnerabilidades do PHP2Shell. O que exatamente a CVE-2026-115560 abrange é explicado na página [CVE-2026-115560: aviso sobre o progresso de upload da sessão](https://phpsos.de/pt/php2shell/cve-2026-115560/).

## O que a função faz e quem precisa dela

O progresso de upload da sessão escreve continuamente na sessão, durante um upload de ficheiro, o progresso, para que uma aplicação possa mostrar uma barra de progresso. No PHP, a função está ativada por defeito. O próprio manual do PHP alerta para o facto de os nomes de ficheiros e de campos fornecidos pelo remetente irem parar, sem verificação, ao armazenamento da sessão e recomenda desativar a função se a aplicação não a utilizar.

Se a sua aplicação a utiliza, descobre-o com uma pesquisa apenas de leitura no código:

```bash
# Procura utilizações da função de progresso no código da aplicação
grep -rn --include="*.php" -e "upload_progress" -e "PHP_SESSION_UPLOAD_PROGRESS" /var/www/
```

Se a pesquisa não encontrar nada, pode desativar a função sem consequências percetíveis. Se houver ocorrências, a aplicação perde apenas o indicador de progresso, não o upload. Os formulários modernos medem, de qualquer modo, o progresso quase sempre no navegador.

## Definir session.upload_progress.enabled no sítio certo

Segundo o manual do PHP, a definição tem o modo `INI_PERDIR`. Isto significa: pode ser definida no php.ini, na configuração do servidor, no `.htaccess` (apenas mod_php) e no `.user.ini` (apenas FPM e CGI), mas não em tempo de execução. O php.net exclui expressamente o `.user.ini` como local para a medida. O quadro seguinte mostra os locais adequados por modo de operação.

| Modo de operação | Local recomendado | Bloqueia contra sobrescrita? | Reiniciar depois |
|---|---|---|---|
| PHP-FPM | ficheiro do pool com `php_admin_flag` | sim | cada serviço FPM |
| PHP-FPM | php.ini da SAPI FPM | não, o `.user.ini` poderia sobrescrever | cada serviço FPM |
| Apache com mod_php | VirtualHost ou configuração do servidor com `php_admin_flag` | sim | Apache por completo |
| php-cgi, LiteSpeed, FrankenPHP | php.ini do respetivo ambiente de execução | verificar consoante a estrutura | todos os processos do ambiente de execução |
| Imagem Docker | ficheiro próprio em `/usr/local/etc/php/conf.d/` na construção | sim, se não for permitida sobrescrita | recriar o contentor |

As duas variantes robustas têm este aspeto:

```ini
; PHP-FPM, p. ex. /etc/php/8.3/fpm/pool.d/seite1.conf
php_admin_flag[session.upload_progress.enabled] = off
```

```apache
# Apache com mod_php, no VirtualHost ou para todo o servidor
<IfModule php_module>
    php_admin_flag session.upload_progress.enabled off
</IfModule>
```

Vale ainda a pena acrescentar a entrada no php.ini de cada SAPI web como valor de base. Assim, a definição aplica-se também a novos pools que alguém crie mais tarde. Por que razão o `php_admin_flag` faz a diferença é descrito no artigo [php_admin_value: bloquear definições contra a sobrescrita](https://phpsos.de/pt/blog/php-admin-value-sperren/).

## Verificar a eficácia no contexto web

A linha de comandos lê muitas vezes um php.ini diferente do do servidor web. Um `php -i` prova, por isso, pouco. Também o `php-fpm8.3 -i` mostra apenas os valores do php.ini, não as entradas dos pools. Só é fiável uma consulta que passe realmente pelo pool.

Proceda assim:

1. Reiniciar todos os serviços PHP, por exemplo `systemctl restart php8.3-fpm` ou o Apache, no caso de mod_php. Sem reinício, o valor antigo continua a correr.
2. Colocar na raiz web um breve ficheiro de teste com nome aleatório, que apenas apresente o valor atual.
3. Chamar o ficheiro uma vez através do domínio real e anotar o resultado.
4. Eliminar o ficheiro de imediato e repetir o passo para cada site e cada pool.

```php
<?php
// Ficheiro de teste: colocar apenas por breves instantes, eliminar logo a seguir
header('Content-Type: text/plain');
echo 'session.upload_progress.enabled = ', var_export(ini_get('session.upload_progress.enabled'), true), "\n";
echo 'PHP ', PHP_VERSION, ' / SAPI ', PHP_SAPI, "\n";
```

Espera-se um valor vazio ou `'0'`. Se aparecer `'1'`, a sua definição não atua nesse pool. Após uma atualização do PHP, verifique ainda se todos os workers foram reiniciados, como descrito em [Reiniciar o PHP-FPM e todos os workers](https://phpsos.de/pt/php2shell/php-fpm-neustart/).

> **Importante:**
> Nunca deixe ficheiros de teste no local. Revelam versões e configuração e são um alvo preferido de análises automatizadas.

## Para que a definição se mantenha

A maioria das recaídas não resulta de atacantes, mas da operação. Um novo pool é copiado de um modelo antigo, uma atualização de pacote cria um novo php.ini ou alguém muda a versão do PHP no painel de alojamento. Contra estas recaídas ajudam hábitos fixos.

- **Cobrir todas as versões:** em muitos servidores correm várias versões do PHP em paralelo. Cada uma tem pastas de configuração próprias e precisa da entrada.
- **Adaptar os modelos:** os modelos de pools, os papéis Ansible, os Dockerfiles e os modelos do painel contêm o valor, para que os novos sites o herdem automaticamente.
- **Usar as definições do painel:** nos painéis de alojamento, o valor pertence às diretivas adicionais previstas pelo painel; caso contrário, a alteração seguinte sobrescreve o trabalho manual.
- **Verificar após as atualizações:** a verificação da secção anterior faz parte da lista de verificação de cada atualização do PHP.
- **Documentar:** registar data, servidor, pools e resultado. Isto ajuda mais tarde perante a gestão, a seguradora ou os auditores.

Quem não utiliza `.user.ini` pode desativar por completo a leitura desses ficheiros com `user_ini.filename =` no php.ini. Isso afeta, porém, todas as definições que as aplicações aí colocam. Teste por isso este passo antes, sobretudo em CMS que escrevem os seus próprios ficheiros `.user.ini`.

As restantes medidas transitórias do php.net, como os limites para o `post_max_size` e o limite de memória por cgroup, estão reunidas em [Medidas imediatas, quando ainda não pode aplicar o patch](https://phpsos.de/pt/php2shell/sofortmassnahmen-ohne-patch/). Como o PHP ordena, em geral, os seus níveis de configuração é explicado em [O php.ini explicado](https://phpsos.de/pt/php/php-ini-erklaert/).

## Como ajuda concretamente a PHP SOS?

- **Fazer o levantamento:** determinamos todas as versões do PHP, modos de operação e pools nos seus servidores e lemos os valores efetivos no contexto web.
- **Definir corretamente:** registamos a definição, bloqueada, nos pools e na configuração do servidor e reiniciamos todos os workers de forma controlada.
- **Testar a função:** verificamos os formulários de upload e a gestão de multimédia após a alteração.
- **Evitar recaídas:** adaptamos modelos, implementações e definições do painel e documentamos o estado no âmbito do [reforço de segurança de servidores](https://phpsos.de/pt/leistungen/server-haertung/).


## Perguntas frequentes

**Por que razão session.upload_progress.enabled=0 não funciona com ini_set()?**  
Segundo o manual do PHP, a definição pertence ao modo INI_PERDIR. Por isso, não pode ser alterada em tempo de execução com ini_set(). O php.net indica como locais corretos o php.ini, o pool FPM ou a configuração do servidor e exclui expressamente o .user.ini.

**Os uploads de ficheiros continuam a funcionar depois de desativar?**  
Sim. Desativa-se apenas a informação de progresso que o PHP escreve na sessão durante um upload. O upload em si continua. Só são afetadas as aplicações que constroem a sua barra de progresso precisamente com esta função do PHP.

**Pode uma aplicação voltar a ativar a função?**  
Através de um ficheiro .htaccess com mod_php ou de um .user.ini com PHP-FPM, é em princípio possível, desde que o valor não esteja bloqueado. Com php_admin_flag no pool ou na configuração do Apache, evita-o.

**Tenho de repor o valor após a próxima atualização do PHP?**  
Não, não é necessário. A função não é necessária à maioria das aplicações e o próprio manual do PHP aconselha a desativá-la nesses casos. Após cada atualização, verifique apenas se o valor continua a aplicar-se.

## Fontes

- [php.net: comunicados de segurança](https://www.php.net/)
- [Manual do PHP: configuração de sessões](https://www.php.net/manual/en/session.configuration.php)
- [Manual do PHP: ficheiros .user.ini](https://www.php.net/manual/en/configuration.file.per-user.php)
