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.
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:
# 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:
; PHP-FPM, p. ex. /etc/php/8.3/fpm/pool.d/seite1.conf
php_admin_flag[session.upload_progress.enabled] = off
# 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.
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:
- Reiniciar todos os serviços PHP, por exemplo
systemctl restart php8.3-fpmou o Apache, no caso de mod_php. Sem reinício, o valor antigo continua a correr. - Colocar na raiz web um breve ficheiro de teste com nome aleatório, que apenas apresente o valor atual.
- Chamar o ficheiro uma vez através do domínio real e anotar o resultado.
- Eliminar o ficheiro de imediato e repetir o passo para cada site e cada pool.
<?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.
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. Como o PHP ordena, em geral, os seus níveis de configuração é explicado em O php.ini explicado.
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.
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.