Em 21 de outubro de 2026, o projeto PHP lançou versões emergenciais para dois bugs críticos que permitiam a um atacante não autenticado executar código em um servidor web. O par é rastreado como CVE-2026-109618 e CVE-2026-109619 e recebeu o nome de PHP2Shell. Ambos pontuam 9,2 no CVSS v4.0, ambos atingem toda configuração PHP que serve HTTP, e os honeypots da Amazon registraram tentativas de exploração em 17 de outubro, quatro dias antes de o patch existir.
O PHP roda em 69,3% dos sites cuja linguagem do lado do servidor é conhecida (W3Techs). Se você mantém uma API PHP, um backend Laravel ou Symfony, um site WordPress ou uma imagem de contêiner com PHP embutido, isso é com você.
Este guia cobre o que os bugs fazem, quais versões são afetadas, como verificar seus servidores, o que as mitigações realmente entregam e como provar que sua API ainda funciona depois de você aplicar o patch.
TL;DR
| Pergunta | Resposta |
|---|---|
| O que é? | Dois bugs de segurança de memória no tratamento de requisições do PHP, encadeados para execução remota de código |
| CVEs | CVE-2026-109618 (corrupção por falta de memória), CVE-2026-109619 (estado obsoleto, use-after-free) |
| Severidade | CVSS v4.0 9,2 cada (IDs vazados antecipadamente diziam 10,0; o PHP diz que isso estava errado) |
| Precisa de autenticação? | Não |
| Afetados | Toda SAPI que serve HTTP: PHP-FPM, Apache mod_php, php-cgi, FrankenPHP, LiteSpeed |
| Versões corrigidas | 8.5.12, 8.4.27, 8.3.36, 8.2.35 |
| PHP 8.1 e anteriores | Sem release oficial; backports mínimos do código-fonte para 7.4, 8.0, 8.1; 5.4 a 7.3 não recebem nada |
| Já explorado? | Tentativas vistas desde 17 de outubro (Amazon), ataques iniciais relatados pela Cloudflare |
| Correção | Atualize, reinicie todos os workers. As soluções de contorno reduzem o risco, mas não o eliminam |
O que o PHP2Shell realmente é
Os dois bugs compartilham uma única causa raiz: o PHP pode deixar sua memória em um estado corrompido quando uma requisição termina de forma anormal, e o código de limpeza então confia nesse estado corrompido.
CVE-2026-109618: corrupção por falta de memória durante a inicialização da requisição. Quando o PHP faz o parsing de dados de formulário para $_POST, o código da tabela hash do motor Zend incrementa seu contador de entradas antes de alocar a nova chave. A análise da Datadog rastreia isso até _zend_hash_str_add_or_update_i() em zend_hash.c. Se essa alocação ultrapassar o memory_limit, o PHP lança um erro fatal e abandona a inserção. O contador agora inclui um bucket que nunca foi configurado. No encerramento, o PHP destrói $_POST e trata cada bucket contado como real.
A parte que deveria preocupar as equipes de API: isso acontece enquanto o PHP ainda está fazendo o parsing do corpo da requisição, antes que uma única linha do seu código seja executada. Seu middleware de autenticação, seu rate limiter e sua validação de entrada nunca veem a requisição. A Datadog reproduziu isso com um corpo application/x-www-form-urlencoded comum, não um upload de arquivo.
CVE-2026-109619: estado global obsoleto entre requisições. O PHP mantém um certo estado de escopo do worker que aponta para memória de escopo da requisição. Se um erro fatal interromper a redefinição desse estado, ou se um diagnóstico tardio de encerramento recriá-lo após a limpeza, a próxima requisição no mesmo worker lê memória já liberada. O PHP confirmou dois caminhos:
- Backtraces de erro fatal (somente PHP 8.5): um diagnóstico de configuração em uma requisição posterior lê estado residual de backtrace. Execução de comandos confirmada no mod_php.
- Processamento de upload: após um erro fatal, o progresso de upload de sessão pode deixar estado para trás para um upload posterior. O progresso de upload vem ativado por padrão e roda mesmo que seu app nunca chame
session_start(). Execução de comandos confirmada no mod_php e no PHP-FPM.
A equipe de segurança do PHP classifica o mod_php como o de maior risco, já que o exploit demonstrado dispara a partir de uma única requisição não autenticada antes de qualquer código da aplicação carregar.
Quem encontrou (e por que a IA está nas manchetes)
Os bugs remontam a código introduzido no PHP 5.4.0, então ficaram na base de código por mais de uma década. A PHP Foundation deu crédito a Calif, OpenAI e Wiz.
Reportagens do Decrypt e do The Next Web dizem que o pesquisador da Calif, Ryan Austin, encontrou as falhas em agosto durante uma auditoria de código-fonte assistida pelo GPT-5.6 Sol da OpenAI. A OpenAI diz que sua própria equipe encontrou uma versão mais completa em setembro, como parte do trabalho "Patch the Planet". A Wiz diz que encontrou os dois bugs por conta própria usando Gemini 4 Argon, Wiz Atlas e GPT-5.6 Sol. O crédito é disputado; a conclusão não é. Auditorias assistidas por IA agora estão encontrando bugs de memória com uma década de idade em infraestrutura crítica, e os atacantes têm os mesmos modelos.
Linha do tempo: por que o patch saiu um dia antes
| Data (2026) | O que aconteceu |
|---|---|
| Agosto a setembro | Calif, OpenAI e Wiz relatam os bugs de forma privada |
| 17 de out | O honeypot MadPot da Amazon registra uma tentativa de exploração |
| 20 de out | IDs de CVE vazam no Hacker News e nas redes sociais; o PHP publica um aviso prévio; a CERT-EU emite o alerta 2026-018 |
| 21 de out, 14:00 UTC | O PHP lança as correções, antecipadas do dia 22 de out após o vazamento; a CISA publica um alerta; a Cloudflare relata ataques iniciais |
| 22 de out | Nenhum dos CVEs está ainda no catálogo KEV da CISA |
A Amazon aconselha investigar a partir de 17 de outubro (o FAQ da Tenable acompanha a linha do tempo completa), não a partir da data de divulgação. No lançamento, a equipe do PHP disse ter inspecionado o código de prova de conceito que apareceu após o vazamento e não ter encontrado nenhum exploit funcional. Desde então, a watchTowr afirmou ter reproduzido os dois bugs. Trate qualquer repositório de "PoC" que encontrar como suspeito: código de exploit não verificado frequentemente traz malware.
Você é afetado? Verifique em cinco minutos
1. Verifique o runtime que atende o tráfego, não o seu notebook. O binário da CLI pode diferir do módulo FPM ou Apache em versão e configuração.
# On the server or inside the running container
php -v
php-fpm -v
# Apache mod_php: check the loaded module version
apachectl -M 2>/dev/null | grep -i php
Ou exponha isso uma vez em uma rota protegida e remova depois:
<?php echo PHP_VERSION, ' ', PHP_SAPI;
2. Compare com as versões corrigidas.
| Branch | Vulnerável | Corrigido em |
|---|---|---|
| 8.5 | < 8.5.12 | 8.5.12 |
| 8.4 | < 8.4.27 | 8.4.27 |
| 8.3 | < 8.3.36 | 8.3.36 |
| 8.2 | < 8.2.35 | 8.2.35 |
| 7.4 a 8.1 | Todos | Apenas backports do código-fonte, ou LTS do fornecedor |
| 5.4 a 7.3 | Todos | Sem correção |
Debian, Ubuntu, Red Hat e outras distros frequentemente fazem backport de correções sem alterar a string de versão upstream. Se php -v mostra um número mais antigo, leia o aviso da sua distro antes de entrar em pânico.
3. Faça o inventário do PHP oculto. Contêineres construídos com FROM php:8.3-fpm meses atrás, appliances de fornecedores, builds compilados por conta própria, painéis administrativos em subdomínios esquecidos. A Cisco já abriu um aviso para verificar sua própria linha de produtos. O Shodan conta mais de 1,9 milhão de hosts PHP expostos à internet; um pesquisador estima que 1,3 milhão ou mais podem estar vulneráveis.
Como aplicar o patch
# Debian / Ubuntu (Ondřej Surý PPA or distro packages)
sudo apt update && sudo apt install --only-upgrade 'php8.*'
# RHEL / Rocky / Alma with Remi
sudo dnf upgrade 'php*'
# Official Docker image: rebuild on a fixed tag
docker pull php:8.4.27-fpm
docker build --pull -t my-api:patched .
Depois, faça o passo que a maioria das equipes esquece: reinicie ou substitua todos os workers PHP. Um pool FPM em execução mantém o binário antigo na memória. Reinicie o php-fpm, recarregue o Apache e faça o rollout de todos os contêineres. O CVE-2026-109619 trata de estado que vive entre requisições dentro de um worker, então um worker não reiniciado continua vulnerável.
No 8.1 ou anterior, você tem três opções: um pacote LTS de fornecedor, compilar a partir do backport do código-fonte do PHP, ou atualizar para 8.2+. A CISA recomenda tirar do ar sistemas PHP que não podem ser corrigidos, e o NCSC do Reino Unido e o FBI disseram o mesmo.
Mitigações se você não puder aplicar o patch hoje
Estas ganham tempo. Gina Peter Banyard, da equipe principal do PHP, disse ao BleepingComputer que nenhuma mitigação bloqueia totalmente os ataques.
Para o CVE-2026-109618:
- Defina
memory_limit=-1onde os apps não possam sobrescrever (php_admin_valueno pool FPM ou na configuração do Apache). Isso bloqueia o caminho conhecido, mas não todas as formas pelas quais uma alocação pode falhar. - Reduza o
post_max_size(8M sem uploads, 32M com uploads). - Limite o tamanho do corpo da requisição no proxy reverso (
client_max_body_sizeno nginx), e defina limites de memória de contêiner ou cgroup como fronteira de disponibilidade. - Não use limites de processo
RLIMIT_ASouRLIMIT_DATA. Eles podem causar justamente as falhas de alocação que o exploit precisa.
Para o CVE-2026-109619:
- Defina
session.upload_progress.enabled=0em configuração que carregue antes do parsing da requisição. - No PHP 8.5, defina também
fatal_error_backtraces=0. - Ocultar erros com
display_errors=0ou@não faz nada. O estado obsoleto continua existindo.
Na borda: a Cloudflare implantou regras de WAF para vetores conhecidos em todos os planos, incluindo o gratuito. Seu CTO as chamou de temporárias.
Após qualquer alteração no php.ini, reinicie todos os workers, ou ela não terá efeito.
Sinais de que você já foi atingido
A orientação de detecção da Datadog se resume a quatro sinais:
- Linha de log:
PHP Fatal error: Allowed memory size of ... bytes exhaustedcomUnknown on line 0. Isso significa que o PHP morreu durante a inicialização da requisição, antes que qualquer script rodasse. - Crashes do Apache:
AH00052: child pid ... exit signal Segmentation fault (11), provavelmente uma tentativa de exploit malsucedida. - Posts de formulário estranhos: um nome de campo com vários megabytes de comprimento, ou bytes binários e nulos em um campo com nome vazio.
- O mais forte: um worker web (
php-fpm,apache2,httpd) gerando um shell.
Não confie nos códigos de status. O exploit refinado da Datadog retornava HTTP 200 e o worker continuava rodando. Pesquise nos logs desde 17 de outubro.
Prove que sua API ainda funciona após o patch: deixe seu agente executar os testes
Aplicar patch no PHP em produção sob pressão é como você descobre que uma atualização de versão menor mudou alguma coisa. Antes e depois de fazer o rollout da correção, rode sua suíte de testes de API no staging e deixe seu agente de código fazer isso com o Apidog CLI.
Configuração (uma vez):
npm install -g apidog-cli
apidog auth login --with-token <your-access-token>
apidog test-suite list --project <projectId>
Um prompt para o Claude Code, Codex ou Cursor:
Acabamos de atualizar o PHP para 8.4.27 no staging por causa do PHP2Shell. Use o Apidog CLI para rodar nossa suíte de testes de regressão contra o ambiente de staging, gere relatórios HTML e JUnit e resuma quaisquer endpoints com falha. Depois confirme que um POST com corpo acima do nosso client_max_body_size do nginx é rejeitado com 413 no proxy em vez de chegar ao PHP.O que o agente executa:
apidog test-suite run <testSuiteId> --project <projectId> -e <stagingEnvId>
apidog run --test-suite <testSuiteId> --project <projectId> -e <stagingEnvId> \
-r cli,html,junit --out-dir ./php2shell-reports --upload-report
-r escolhe os reporters, --out-dir define onde os relatórios ficam e --upload-report envia um resumo que você pode abrir no app Apidog. Adicione --notification-failed-event <targetId> para avisar sua equipe somente quando algo quebrar. Coloque a mesma linha apidog run no CI para que toda imagem PHP reconstruída seja testada antes de ser publicada. O guia de configuração do Claude Code e o tutorial do pipeline de CI/CD cobrem ambos em detalhes.
Rode a suíte uma vez na versão antiga para obter uma linha de base, uma vez após a atualização, e compare. Se um teste que você nunca esperava falhar falhar, você saberá antes dos seus usuários. Baixe o Apidog para criar e gerenciar as suítes que o CLI executa.
Perguntas frequentes
O PHP2Shell está sendo explorado? A Amazon viu tentativas desde 17 de outubro e diz que agora é amplamente explorado; a Cloudflare e a watchTowr também relatam ataques. A CISA não havia confirmado exploração até 22 de outubro.
Meu framework me protege? Não. O CVE-2026-109618 dispara enquanto o PHP faz o parsing do corpo, antes de Laravel, Symfony ou WordPress carregarem.
Estou em hospedagem compartilhada. O que faço? Verifique a página de status do seu provedor. A SiteGround e outros dizem que já aplicaram o patch. Se o seu não disse nada, pergunte.
session.upload_progress.enabled=0 é suficiente? Não. Cobre um caminho de um CVE. Aplique o patch.
Preciso rotacionar segredos? O CVE-2026-109619 permite divulgação de memória. Se os logs mostrarem sinais de comprometimento desde 17 de outubro, rotacione senhas de banco de dados, chaves de API e segredos de sessão que o processo PHP poderia ler.
A conclusão
Atualize para 8.5.12, 8.4.27, 8.3.36 ou 8.2.35. Reinicie todos os workers. Encontre o PHP que você esqueceu. Verifique os logs desde 17 de outubro. Depois rode seus testes de API para que a correção não se torne a próxima indisponibilidade. Se o seu PHP está na 8.1 ou anterior, esta é a semana de finalmente sair dela.
