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 = 0bloqueia 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_sizede 8M sem uploads, ou 32M se o site aceitar ficheiros, comupload_max_filesizeabaixo 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 = -1definido 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 useRLIMIT_ASnemRLIMIT_DATApara 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
- PHP por pacotes (Debian, Ubuntu, RHEL, AlmaLinux). Instale a atualização de segurança (
apt update && apt upgrade, oudnf 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. - Imagens Docker. Reconstrua sobre uma tag corrigida (
php:8.4-fpmaponta agora para 8.4.27) comdocker compose build --pulle depois recrie os contentores. Um contentor em execução mantém o PHP antigo até ser substituído. - 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.
- 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.
