Partilhe:

Medidas de contenção PHP2Shell: execução remota de código no PHP

22 Out 2026 Notícias

Oramix Security Advisory

O PHP corrigiu a 21/10/2026 duas falhas críticas que permitem a um atacante remoto, sem credenciais, executar código no servidor através de pedidos HTTP. A 20/10 o projeto PHP anunciou uma versão de segurança iminente e, a 21/10, os detalhes técnicos e as primeiras provas de conceito já circulavam publicamente. O CERT-EU considera que isto aumenta a probabilidade de já haver exploração, por isso o risco sobe depressa.

Quem está em maior risco

Servidores com Apache mod_php, a única configuração com RCE completo validado por HTTP e que a equipa PHP considera a mais exposta. O FrankenPHP chama o encerramento do pedido incondicionalmente, tal como o mod_php, pelo que a análise de código o indica como provavelmente suscetível a ataques independentes da aplicação, sem exploit validado. O ataque corre antes do código da aplicação, por isso WAF aplicacional, validação de input e boas práticas de código não o impedem.

Todas as instalações PHP que servem pedidos web estão em risco (PHP-FPM, mod_php, php-cgi, FrankenPHP e LiteSpeed). No PHP-FPM e no LSAPI, que modela o FPM, os exploits dependem da aplicação ou da configuração: no FPM há caminhos validados e, no LSAPI, exploits prováveis mas não validados. No CVE-2026-109619 o LSAPI é um candidato condicional, porque pode aplicar valores INI de ambiente cedo; no FrankenPHP não foi estabelecido um consumidor equivalente na configuração por defeito, o que não o torna imune. Nada disto justifica adiar a atualização.

Consequência prática de um comprometimento

O atacante passa a correr comandos como o utilizador do worker PHP. Isso dá acesso ao código da aplicação, a ficheiros de configuração com credenciais (base de dados, chaves de API), aos dados que a aplicação trata e a um ponto de partida para movimento lateral. Esta é a consequência típica de um RCE nesse contexto e não um dado específico do advisory.

Versões

Corrigido em: PHP 8.5.12, 8.4.27, 8.3.36 e 8.2.35. PHP 8.1 e anteriores já não recebem versões oficiais (o descobridor refere impacto desde o 5.4). Algumas distribuições e fornecedores LTS têm backports, e a equipa PHP publicou backports mínimos em código-fonte para o 7.4, 8.0 e 8.1 (CERT-EU). Contactar o fornecedor ou migrar. O 8.2 perde suporte de segurança a 31/12/2026.

 CVE-2026-109618CVE-2026-109619
O que éFalta de memória (OOM) durante um pedido deixa dados internos do PHP a meio da inicialização. O encerramento do pedido usa-os como se fossem válidos.Estado global de um pedido fica preso no worker e aponta para memória já libertada. Um pedido seguinte, no mesmo worker, usa-o (use-after-free).
ImpactoExecução remota de código sem autenticação, com os privilégios do utilizador do servidor web.Use-after-free com divulgação de memória e execução remota de código sem autenticação, com os privilégios do utilizador do servidor web.
Como é atingidoPedido HTTP multipart desenhado para esgotar memória (sem Content-Length, muitos cabeçalhos ou campos vazios) sem passar os limites aparentes do PHP.Dois passos: um pedido provoca um erro fatal ou OOM que deixa estado por repor; outro pedido no mesmo worker consome esse estado antes da inicialização normal.
Em mod_phpExploit completo validado por HTTP com limites por defeito, antes de qualquer código da aplicação correr. Funciona independentemente da aplicação.Exploit confirmado em PHP 8.5 com fatal_error_backtraces ativo; o progresso de upload de sessão também serve de consumidor.
Em PHP-FPMSuscetível pela análise do código; não há exploit completo demonstrado.RCE validado também em FPM (ciclo de vida do upload de sessão), mas depende de uma operação adequada da aplicação. Exposição condicional via PHP_VALUE enviado pelo servidor web.
DificuldadeAlta (AC:H). Exige afinar o consumo de memória.Alta (AC:H). Exige combinar produtor e consumidor.

Boas práticas e medidas compensatórias (aplicáveis desde já)

Atualizar é a única mitigação completa: não existe mitigação genérica por configuração. Até o patch estar em produção, aplicar em conjunto as medidas dos dois CVE, porque cada advisory remete para o outro.

1. Remediação definitiva

  • Atualizar para PHP 8.5.12, 8.4.27, 8.3.36 ou 8.2.35 (ou release posterior do mesmo ramo).
  • Reiniciar todos os workers e confirmar a versão realmente em execução.
  • PHP 8.1 e anteriores: sem versões oficiais. Contactar o fornecedor ou a distribuição para um backport, usar os backports mínimos em código-fonte publicados pela equipa PHP (7.4, 8.0 e 8.1) ou migrar.
  • Pacotes de distribuição: as distribuições e fornecedores LTS receberam os patches antecipadamente, por isso confirmar com o fornecedor. O repositório rpms.remirepo.net não terá atualizações no dia da publicação; a equipa PHP aconselha pacotes da distribuição ou compilação a partir do código-fonte.
  • Software de terceiros que embebe PHP: produtos comerciais e open source com PHP como backend podem estar afetados mesmo sem expor uma instalação PHP. O CERT-EU recomenda consultar o repositório NCSC-NL php2shell para os identificar.
  • Se não for possível atualizar já: o CERT-EU recomenda considerar isolar as aplicações expostas à internet das redes públicas até a correção ser aplicada e verificada.
  • Prioridade por SAPI: Apache mod_php e FrankenPHP primeiro (o ataque do CVE-2026-109618 corre antes do código da aplicação); depois PHP-FPM, php-cgi e LiteSpeed, com as mesmas medidas.

2. CVE-2026-109618 (falta de memória)

  • Impor memory_limit=-1 ao nível administrativo (por exemplo php_admin_value no pool FPM) e confirmar que nenhum pool, diretório ou aplicação repõe um limite finito. Remove o limite previsível que torna o exploit controlável. Custo: sem limite por pedido, um pedido abusivo pode consumir a memória do servidor, o que pesa em hosts partilhados.
  • Limitar o pedido no frontend (proxy ou servidor web): impor o tamanho decodificado do pedido, o número de campos, de partes multipart, de cabeçalhos e a profundidade de aninhamento, incluindo pedidos sem um Content-Length utilizável.
  • Definir post_max_size baixo: 8M para aplicações sem uploads e 32M se forem necessários, mantendo upload_max_filesize abaixo de post_max_size.
  • Reduzir max_input_nesting_level e o número de variáveis de input.
  • Bloquear multipart no frontend se a aplicação não o utiliza, para que o pedido nunca chegue ao PHP.
  • Limite de memória por cgroup (memory.max) apenas como apoio, idealmente um cgroup por worker. Se for global, matar o contentor derruba o master e todos os workers.
  • Nunca usar RLIMIT_AS nem RLIMIT_DATA: fazem o mmap() falhar e ativam precisamente o caminho vulnerável.

3. CVE-2026-109619 (estado obsoleto entre pedidos)

  • Desativar session.upload_progress.enabled (session.upload_progress.enabled=0) e reiniciar todos os workers. Aplicar em php.ini, no pool FPM ou numa configuração do servidor que atue antes do parsing do pedido; não confiar em ini_set() nem em .user.ini. Está ativo por defeito e não exige session_start(). Bloqueia os caminhos de sessão confirmados, mas não outras variantes.
  • PHP 8.5: fatal_error_backtraces=0 e reiniciar todos os workers. Bloqueia apenas o caminho confirmado do backtrace de erros fatais, que é o produtor do RCE demonstrado.
  • Eliminar diagnósticos de INI aplicados antes da inicialização: @, error_reporting e display_errors não protegem. Preferir php.ini, pool FPM ou configuração do servidor aplicados no arranque, em vez de overrides por pedido. Verificar PHP_VALUE e PHP_ADMIN_VALUE enviados por nginx ou mod_proxy_fcgi, .htaccess e php_value/php_flag/php_admin_* no Apache, e valores inválidos (memory_limit, date.timezone, zend.assertions, mbstring.*, iconv.*, caminhos rejeitados por open_basedir).
  • Eliminar erros fatais alcançáveis por um atacante: parse errors, require falhado, erros não capturados e “Maximum execution time exceeded” em caminhos de upload, importação, páginas de erro, shutdown, destrutores, serialização, output handlers, plugins e callbacks. Eliminar também warnings emitidos durante o cleanup de extensões e do servidor.
  • pm.max_requests=1 quebra a ligação entre pedidos no mesmo worker. É caro em desempenho, por isso usar apenas como medida temporária.

4. Auditoria e deteção

  • Num ambiente isolado, ativar log_errors=On, um error_log funcional e error_reporting=E_ALL na configuração de arranque.
  • Rever os logs do Apache, FPM, proxy e serviços à procura de warnings e deprecations repetidos antes de o script alvo correr, diagnósticos durante o cleanup de extensões, erros fatais, parse errors, uncaught errors e “Maximum execution time exceeded”.
  • Limites da auditoria: a ausência de erros nos logs não prova segurança. Os logs históricos podem ter excluído deprecations, só cobrem as rotas exercitadas e uma falha pode ocorrer antes de o PHP escrever a mensagem. Complementar com auditoria estática da configuração e dos fluxos da aplicação.

Nenhuma destas medidas é completa. Servem para reduzir a exposição enquanto a atualização não é aplicada. Precisa de ajuda na correção? Fale com a nossa equipa de cibersegurança.