PHP2Shell: verificar e corrigir as falhas RCE do PHP

PHP2Shell: verificar e corrigir as falhas RCE do PHP

PHP2Shell: verificar e corrigir as falhas RCE do PHP

Em 21 de outubro de 2026 o projeto PHP lançou as versões 8.5.12, 8.4.27, 8.3.36 e 8.2.35 para corrigir duas falhas no próprio PHP, apelidadas de PHP2Shell. Ambas permitem que um pedido de alguém sem sessão iniciada execute código como o worker do PHP. O erro está no runtime, não no WordPress, Drupal ou Joomla, por isso atualizar o CMS ou os seus plugins não o resolve. Este guia mostra quem é afetado, como verificar um servidor com um só comando, o que fazer hoje se ainda não puder atualizar e como atualizar com segurança.

O que são as duas falhas

  • CVE-2026-109618, corrupção por falta de memória - quando uma alocação de memória falha, o PHP pode interromper um pedido enquanto os seus dados internos estão só meio preparados, e a limpeza que se segue confia nesses dados danificados. Um pedido multipart forjado pode provocá-la mesmo dentro dos limites de tamanho que configurou.
  • CVE-2026-109619, estado global obsoleto - o estado que pertence a um pedido pode sobreviver à memória que o suporta. O pedido seguinte servido pelo mesmo worker pode usar essa memória libertada antes de ela ser reposta (um use-after-free). O caminho confirmado passa pela funcionalidade session upload progress e por erros fatais.

Ambas têm pontuação 9.2 (crítica) no CVSS 4.0. O anúncio do PHP diz que foi construído um exploit funcional durante a investigação e que o risco é maior no Apache com mod_php, onde o ataque corre antes de qualquer código da aplicação. Em poucos dias surgiram vários exploits públicos de prova de conceito; a Rapid7 relata que cada um só funciona para uma combinação de sistema operativo, versão do PHP e servidor web, e já viu tentativas de exploração. Trate isto como um patch de emergência.

Quem é afetado

Todas as instalações de PHP que servem pedidos web: PHP-FPM, Apache com mod_php, php-cgi, FrankenPHP e LiteSpeed. Isso abrange quase todos os servidores com WordPress, WooCommerce, Drupal, Joomla, Magento, Laravel e Nextcloud.

Ramo do PHP Afetadas Primeira versão corrigida
8.5 8.5.0 - 8.5.11 8.5.12
8.4 8.4.0 - 8.4.26 8.4.27
8.3 8.3.0 - 8.3.35 8.3.36
8.2 8.2.0 - 8.2.34 8.2.35
7.4, 8.0, 8.1 todas sem versão no php.net; backports no código-fonte, pacotes da distribuição ou de um fornecedor LTS
7.3 e anteriores todas sem correção

As distribuições mantêm muitas vezes o número de versão antigo e aplicam a correção por backport (por exemplo, um pacote Debian ou Ubuntu que continua a indicar 8.2.x). Com PHP instalado por pacotes, consulte por isso o pacote no security tracker da sua distribuição, não apenas o número.

Verificar um servidor com um só comando

Guarde isto como php2shell-check.php e execute-o com o mesmo PHP que serve o seu site. Mostra a versão, se essa versão é anterior à correção e as duas definições que as medidas provisórias abaixo alteram.

<?php
// PHP2Shell check: is this PHP build older than the October 21, 2026 fixes?
$fixed = ['8.5' => '8.5.12', '8.4' => '8.4.27', '8.3' => '8.3.36', '8.2' => '8.2.35'];
$branch = PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION;
echo "PHP " . PHP_VERSION . " (" . PHP_SAPI . ")\n";
if (!isset($fixed[$branch])) {
    echo "Branch $branch gets no php.net release: check your distro or LTS vendor, or upgrade to 8.4.\n";
} elseif (version_compare(PHP_VERSION, $fixed[$branch], '<')) {
    echo "VULNERABLE: upgrade to {$fixed[$branch]} or later (or a distro build with the backport).\n";
} else {
    echo "Patched upstream version ({$fixed[$branch]}+).\n";
}
echo "session.upload_progress.enabled = " . (ini_get('session.upload_progress.enabled') ? 'On' : 'Off') . "\n";
echo "post_max_size = " . ini_get('post_max_size') . ", memory_limit = " . ini_get('memory_limit') . "\n";
php php2shell-check.php

Saída verificada em 2026-10-24 nas imagens Docker oficiais php:

PHP 8.3.30 (cli)
VULNERABLE: upgrade to 8.3.36 or later (or a distro build with the backport).
session.upload_progress.enabled = On
post_max_size = 8M, memory_limit = 128M
PHP 8.4.27 (cli)
Patched upstream version (8.4.27+).
PHP 7.2.34 (cli)
Branch 7.2 gets no php.net release: check your distro or LTS vendor, or upgrade to 8.4.

O php da linha de comandos pode ser um build diferente do que está por trás do seu site. Para verificar o lado web, execute php-fpm -v (ou php-fpm8.3 -v em Debian e Ubuntu), ou coloque o script na raiz web durante um único pedido e apague-o logo a seguir.

Se não puder atualizar hoje: medidas provisórias

A equipa do PHP é clara: não há mitigação completa e atualizar é a única opção segura. Estas definições reduzem o ataque enquanto agenda a atualização. Defina-as onde a aplicação não as pode substituir - no php.ini ou no pool do FPM com php_admin_value -, porque ini_set() e .user.ini aplicam-se tarde demais. Depois reinicie todos os workers.

; FPM pool, e.g. /etc/php/8.3/fpm/pool.d/zz-php2shell.conf (the [www] section of your pool)
[www]
php_admin_value[session.upload_progress.enabled] = 0
php_admin_value[post_max_size] = 32M
php_admin_value[upload_max_filesize] = 30M
php-fpm8.3 -t && systemctl restart php8.3-fpm

Verificámos este ficheiro de pool com php-fpm -t no PHP 8.4 (configuration test successful). O que faz cada linha:

  • session.upload_progress.enabled = 0 bloqueia o caminho confirmado da CVE-2026-109619, não todas as variantes. Desative-o, a não ser que uma barra de progresso de upload dependa dele.
  • post_max_size de 8M sem uploads, ou 32M se o site aceitar ficheiros, com upload_max_filesize abaixo disso, como recomenda a equipa do PHP. Limite também o tamanho dos pedidos no nginx (client_max_body_size 32m;) ou no Apache (LimitRequestBody).
  • Apenas no PHP 8.5, acrescente fatal_error_backtraces = 0.
  • O PHP sugere ainda memory_limit = -1 definido pelo administrador, para que o próprio limite de memória não possa ser usado para provocar a CVE-2026-109618. Faça isso só com um limite de memória de contentor ou cgroup à volta do PHP, caso contrário um único pedido malicioso pode ocupar toda a RAM do servidor. Não use RLIMIT_AS nem RLIMIT_DATA para isto: podem provocar a falha.

Esconder erros (display_errors, error_reporting, @) não ajuda, e um log de erros vazio não prova que um servidor não foi atacado.

Como atualizar

  1. PHP por pacotes (Debian, Ubuntu, RHEL, AlmaLinux). Instale a atualização de segurança (apt update && apt upgrade, ou dnf upgrade 'php*') e depois reinicie o PHP-FPM ou o Apache, porque os workers em execução mantêm o código antigo. Confirme que o changelog do pacote menciona a CVE-2026-109618.
  2. Imagens Docker. Reconstrua sobre uma tag corrigida (php:8.4-fpm aponta agora para 8.4.27) com docker compose build --pull e depois recrie os contentores. Um contentor em execução mantém o PHP antigo até ser substituído.
  3. PHP 7.4 - 8.1. Use o pacote com backport do seu fornecedor, ou passe para 8.4. O PHP 7.3 e anteriores nunca terão correção: coloque o site atrás de uma lista de permissões ou de uma VPN até ser migrado.
  4. Depois da atualização, volte a executar o script de verificação e procure no log do servidor web pedidos POST multipart invulgares e falhas de workers do PHP desde 21 de outubro.

Se precisar de ajuda, a administração gerida de servidores inclui patches como este, e o nosso guia de servidor cloud para WordPress mostra uma configuração PHP-FPM que mantém estas definições no pool. Antes de atualizar um site em produção, faça um snapshot: backup e restauro de uma VM explica como.

O que fizemos

Na mesma semana verificámos cada serviço da DCXV que usa PHP e aplicámos as medidas deste guia. Os servidores dos clientes são geridos pelos seus donos: se corre PHP num servidor cloud ou dedicado da DCXV, faça hoje a verificação acima. Um novo servidor cloud recebe os pacotes atuais no primeiro apt upgrade.

Fontes (consultadas em 2026-10-24): o anúncio das versões de segurança do PHP 8.x de 21 de outubro de 2026, os avisos do PHP GHSA-w8hw-w9fx-j79w e GHSA-6wmf-4rv5-p3rp e a análise da Rapid7.

Starlink Mini 2 atrás de CGNAT: como chegar a um local que muda
networkingcloudinfrastructure

Starlink Mini 2 atrás de CGNAT: como chegar a um local que muda

A Starlink Mini 2 chegou, mas os planos normais ficam atrás de CGNAT. Contámos 990.208 IPv4 para 12+ milhões de clientes e comparamos quatro formas de acesso.

Protestos contra centros de dados na Europa: o que fazer
clouddedicatedinfrastructure

Protestos contra centros de dados na Europa: o que fazer

A 6 de novembro, centenas entraram na obra da Microsoft em Amesterdão. Os números da rede neerlandesa, a latência medida a hubs da UE e o que fazer agora.

EUA rejeitam centros de dados 45 a 1: lições para clientes
clouddedicatedinfrastructure

EUA rejeitam centros de dados 45 a 1: lições para clientes

47 votações sobre centros de dados nos EUA, o lado restritivo venceu em 45. Recontamos os dados brutos e explicamos o que muda para quem aluga servidores.

AWS BYOIP em 2026: $43.80 por IPv4 ou o seu próprio /24
ipv4pricingcloud

AWS BYOIP em 2026: $43.80 por IPv4 ou o seu próprio /24

A AWS cobra $0.005 por hora por IPv4 público, $43.80 por ano. O BYOIP não paga isso: quando um /24 comprado ou alugado compensa, com uma verificação de ROA.

Sair do VMware após a Broadcom: guia de migração verificado
clouddedicatedinfrastructure

Sair do VMware após a Broadcom: guia de migração verificado

A Broadcom acabou com licenças perpétuas, cortou parceiros e escondeu o VDDK. Como mover VMs para KVM, Proxmox ou Hyper-V, com datas e uma conversão OVA testada.