Situação atual: PHP2Shell. Duas vulnerabilidades críticas do PHP (CVSS 9,2) permitem executar código malicioso sem autenticação. Patches disponíveis desde 21/10/2026.O que fazer agora →

Definir corretamente o memory_limit

O memory_limit limita a memória de cada pedido PHP. Após o PHP2Shell, o php.net aconselha temporariamente o contrário. O que vale em operação normal, na fase transitória e depois da atualização.

Atualizado em 6 min de leituraHardening e configuração

Em resumo: O memory_limit define quanta memória um único pedido PHP pode ocupar; o valor por defeito é 128M. Em operação normal, defina um valor finito adequado à aplicação e bloqueie-o com php_admin_value. Enquanto o PHP2Shell não estiver corrigido, o php.net aconselha temporariamente memory_limit=-1, que não possa ser sobrescrito e combinado com um limite através de contentor ou cgroup, não através de RLIMIT_AS ou RLIMIT_DATA. Depois da atualização, volta a valer um valor finito.

Uma definição de rotina que de repente é um tema de segurança

Durante anos, o memory_limit foi um parâmetro para programadores. Se um site comunica «Allowed memory size exhausted», aumenta-se o valor e o problema fica resolvido. Com o PHP2Shell, passou a ser uma questão de segurança, e a recomendação do php.net parece, à primeira vista, paradoxal: para a fase transitória, o limite de memória do próprio PHP deve ser totalmente eliminado.

O contexto é a CVE-2026-109618. Segundo o projeto PHP, um estado de falta de memória pode interromper o PHP enquanto os dados do pedido estão apenas parcialmente inicializados. A limpeza do pedido pode então tratar dados inválidos como válidos. Os pormenores técnicos estão em CVE-2026-109618; o que acontece no interior do PHP em caso de falta de memória é explicado em memory_limit e Out-of-Memory. Para os operadores, a questão é: que valor vale quando, e onde tem de estar?

O que o memory_limit faz em operação normal

Segundo o manual do PHP, o memory_limit limita a memória que um script pode ocupar e protege assim o servidor de código mal escrito. O valor por defeito é 128M, e -1 significa sem limite. São permitidas notações abreviadas como 256M ou 1G.

Duas características são importantes para a segurança. Primeiro, o valor pode ser alterado em qualquer lado, também em tempo de execução com ini_set(). Muitos CMS e lojas aumentam-no por si próprios, por exemplo para importações ou processamento de imagens. Quem quiser impor um valor tem de o definir com php_admin_value; segundo o manual, os valores assim definidos não podem ser sobrescritos com ini_set(). Segundo, o manual recomenda que o memory_limit seja superior a post_max_size.

O valor adequado depende da aplicação. Uma vista ao registo de erros mostra se ocorrem mensagens de memória esgotada e em que chamadas. Tem-se revelado eficaz definir o valor para cada site no respetivo pool FPM: mais generoso para uma loja com importações, mais curto para um site institucional simples. Um valor muito alto e generalizado para todos os sites desperdiça o efeito protetor, porque então um único pedido defeituoso ou abusivo pode ocupar muita memória.

Desde o PHP 8.5 existe ainda max_memory_limit. Esta definição só pode ser fixada no arranque e limita até que valor o memory_limit pode ser definido. Os valores mais altos são cortados com um aviso. O valor por defeito -1 significa que não há limite máximo.

memory_limit após o PHP2Shell: a medida transitória do php.net

Para servidores que ainda não foram atualizados para 8.5.12, 8.4.27, 8.3.36 ou 8.2.35, ou para um backport confirmado, o php.net indica, no comunicado de segurança de 21/10/2026, os seguintes passos. Reduzem o risco de alguns caminhos de ataque, mas, segundo o php.net, não tornam uma instalação segura:

  1. Definir memory_limit=-1, se possível de modo que as aplicações não possam sobrescrever o valor, por exemplo com php_admin_value no pool FPM ou na configuração do Apache.
  2. Verificar que em lado nenhum volta a ser definido um limite finito, nem noutro pool, nem numa configuração de diretório, nem na aplicação.
  3. Definir um limite de memória através de contentor ou cgroup, como proteção da disponibilidade, se possível de modo que, em caso de excesso, apenas o worker afetado seja terminado.
  4. Não usar RLIMIT_AS nem RLIMIT_DATA. Segundo o php.net, esses limites podem desencadear precisamente o erro vulnerável na atribuição de memória.

O php.net explica a este respeito que -1 elimina a possibilidade de atingir de forma provocada o limite de memória do PHP, mas que um erro de memória a um nível mais profundo pode continuar a alcançar o caminho vulnerável. A visão geral de todas as medidas transitórias está em Medidas imediatas, quando ainda não pode aplicar o patch.

; Pool FPM, p. ex. /etc/php/8.3/fpm/pool.d/www.conf (apenas até à atualização)
php_admin_value[memory_limit] = -1
# Onde é definido o memory_limit (apenas leitura)
grep -rn 'memory_limit' /etc/php/ /etc/apache2/ 2>/dev/null
grep -rn --include='*.php' -E "ini_set\s*\(\s*['\"]memory_limit" /var/www | head -20
grep -rn --include='.user.ini' 'memory_limit' /var/www

Como definir o limite cgroup para o serviço FPM é descrito em Definir limites de memória com systemd e cgroups. Sem este limite exterior, um único pedido pode levar o servidor inteiro a uma situação de falta de memória.

Importante

Após cada alteração, reinicie todos os workers PHP. Um worker em execução mantém os valores antigos.

O que vale depois da atualização

Com as versões corrigidas, segundo o manual do PHP, também mudou o comportamento do memory_limit. A partir de 8.5.12, 8.4.27, 8.3.36 e 8.2.35, é um limite flexível: um pedido de memória que o ultrapasse pode, na maioria dos casos, ainda ser concluído antes de o erro ser desencadeado. Uma nova definição, memory_hard_limit_percent, estabelece um limite rígido que nunca é excedido.

Definição Valor Efeito segundo o manual
memory_hard_limit_percent não definido ou -1 por defeito limite rígido duas vezes superior ao memory_limit até 1G; acima disso, memory_limit mais 1G
memory_hard_limit_percent = 150 exemplo com memory_limit=128M, limite rígido de 192M
memory_limit = -1 sem limite então também não há limite rígido

O manual indica um ponto de verificação prático: se memory_hard_limit_percent não for reconhecido, a versão do PHP em uso está afetada e tem de ser atualizada. Nos backports das distribuições, verifique o estado também através do changelog do pacote.

# O binário FPM conhece a nova definição? (ajustar o número de versão)
php-fpm8.3 -i | grep -E 'memory_hard_limit_percent|memory_limit'

Após a atualização, o memory_limit=-1 cumpriu a sua finalidade. Volte a um valor finito, adequado à aplicação, e bloqueie-o com php_admin_value. O limite cgroup pode manter-se como camada de proteção adicional.

Como ajuda concretamente a PHP SOS?

  • Determinamos onde, no seu servidor, o memory_limit é definido e sobrescrito, incluindo pelas aplicações.
  • Aplicamos as medidas transitórias do php.net no sítio certo e acrescentamos um limite cgroup para o serviço FPM.
  • Através do serviço de patches PHP, levamos o PHP para uma versão corrigida e reiniciamos todos os workers.
  • Depois, voltamos a definir um valor finito adequado e documentamos as definições.

Perguntas frequentes

Qual é o valor por defeito do memory_limit?

Segundo o manual do PHP, 128M. O valor limita a memória que um único script pode ocupar. Pode ser alterado no php.ini, na configuração do servidor, no pool FPM e em tempo de execução com ini_set(), desde que não esteja bloqueado com php_admin_value.

Por que razão o php.net recomenda memory_limit=-1 no caso do PHP2Shell?

Uma das vulnerabilidades, a CVE-2026-109618, está relacionada com o estado em caso de falta de memória. Segundo o php.net, memory_limit=-1 elimina a possibilidade de atingir de forma provocada o limite de memória do PHP, mas não todos os erros de memória. A medida não é uma proteção completa e tem de ser combinada com um limite de memória através de contentor ou cgroup.

Posso, em alternativa, definir o limite com ulimit?

Não. O php.net desaconselha expressamente usar RLIMIT_AS ou RLIMIT_DATA como substituto, porque esses limites podem desencadear precisamente o erro vulnerável na atribuição de memória. Recomenda-se um limite através de contentor ou cgroup.

O que vale depois da atualização para uma versão corrigida do PHP?

Segundo o manual, nas versões corrigidas o memory_limit é um limite flexível, complementado por um limite rígido através de memory_hard_limit_percent. A medida transitória com -1 cumpriu então a sua finalidade e deve voltar a aplicar-se um valor finito, adequado à aplicação.

Fontes

Contacto imediato

Cada hora conta. Escreva-nos agora.

Descreva brevemente o sistema, a versão do PHP e o que observou. Entramos em contacto consigo, esclarecemos a situação e trabalhamos remotamente até o incidente estar concluído e documentado.

Ajuda imediata