E não é que o PHP voltou a ser um dos assuntos mais comentados da internet mundial? 🐘
Quem diz que o PHP morreu deve ter levado um susto: na semana passada ele apareceu no g1 e na CNN, fez governos na Europa tirarem sites do ar e até o FBI e a NSA soltaram alerta. Só que, dessa vez, o motivo não foi uma feature nova.
O PHP lançou uma release de emergência pra corrigir duas vulnerabilidades que permitem execução remota de código sem autenticação, apelidadas de PHP2Shell: a CVE-2026-109618 e a CVE-2026-109619.
Se você não tiver tempo pra ler o resto, leve só isso: se o seu servidor roda PHP atendendo requisições web, atualize para 8.5.12, 8.4.27, 8.3.36 ou 8.2.35 (ou superior).
Sumário
- Antes, o que é uma CVE?
- O que aconteceu
- As duas falhas
- Quem está em risco e qual a gravidade?
- Fake news e exageros
- Como o PHP corrigiu
- Como saber se estou vulnerável?
- Não consigo atualizar agora, e aí?
- Então o PHP acabou? Claro que não
- Manter atualizado não é opcional
- Conclusão
Antes, o que é uma CVE?
Se você nunca precisou lidar com isso, três siglas vão aparecer bastante por aqui:
- CVE (Common Vulnerabilities and Exposures) é o "RG" de uma falha de segurança. Cada vulnerabilidade conhecida recebe um identificador único, como
CVE-2026-109618: o ano e um número. Assim, todo mundo (desenvolvedores, empresas, distros e ferramentas de segurança) fala da mesma falha sem confusão; - CVSS (Common Vulnerability Scoring System) é a nota de gravidade, de 0 a 10. Acima de 9 é considerada crítica;
- RCE (Remote Code Execution) é o pior tipo de falha: o atacante consegue executar código no seu servidor pela rede, como se tivesse acesso a ele.
Ou seja, quando alguém diz "CVE crítica com RCE", está dizendo: falha catalogada, gravidade na faixa mais alta da escala, e o atacante pode assumir o servidor.
O que aconteceu
A release estava marcada para 22/10, mas no dia 20 os IDs das CVEs vazaram nas redes com uma nota errada, e logo depois a Calif, empresa que reportou as falhas, publicou por engano um vídeo do exploit. O PHP antecipou tudo em um dia.
Aí o assunto saiu da bolha dev. O CERT-EU recomendou tirar do ar os sites afetados, e governos da Finlândia, Holanda, França e Alemanha desligaram páginas oficiais. Nos Estados Unidos, o FBI publicou um alerta recomendando atualizar imediatamente e, se não der, tirar o sistema do ar. Aqui no Brasil, a Anatel e tribunais suspenderam o SEI por precaução. A imprensa toda cobriu, inclusive o g1, que contou que a brecha foi descoberta há dois anos.
E é verdade. Segundo a PHP Foundation, os primeiros sinais do problema apareceram numa auditoria de 2024, mas a correção travou por meses. Só virou prioridade máxima em agosto de 2026, quando a Calif e a OpenAI reportaram a mesma falha, ambas usando IA na pesquisa. A própria Foundation chamou o atraso de "uma falha estrutural", por falta de recursos e de um processo de decisão lento. Achei muito honesto da parte deles.
As duas falhas
CVE-2026-109618: o OOM que deixa a casa bagunçada
Quando o PHP estoura o memory_limit, ele usa longjmp() pra abandonar a requisição na hora. O problema é que, em alguns pontos, a memória da requisição ainda não foi totalmente inicializada, e o shutdown depois lê essa memória como se fosse válida.
No Apache com mod_php, isso acontece durante o parsing do corpo da requisição. Ou seja, não importa se o seu código é seguro: basta ter PHP respondendo HTTP. Detalhes no advisory GHSA-w8hw-w9fx-j79w.
CVE-2026-109619: o lixo que fica pra próxima requisição
Os workers do PHP atendem várias requisições no mesmo processo. Se um erro fatal ou um OOM interrompe uma requisição, alguns ponteiros globais não são zerados. A memória é liberada, mas a próxima requisição no mesmo worker usa esse ponteiro velho. Um use after free clássico.
Os casos confirmados envolvem o fatal_error_backtraces do PHP 8.5 e o session upload progress, que vem habilitado por padrão. E um detalhe importante: usar @ ou desligar o display_errors não protege. Detalhes no advisory GHSA-6wmf-4rv5-p3rp.
Quem está em risco e qual a gravidade?
Segundo o PHP, toda instalação que atende requisições web. O risco muda conforme a SAPI (a forma como o PHP roda no servidor) e é maior no mod_php:
| SAPI | CVE-2026-109618 (OOM) | CVE-2026-109619 (estado global) |
|---|---|---|
| Apache mod_php | Exploit confirmado, sem depender da aplicação | Exploit confirmado |
| PHP-FPM | RCE confirmada, via código da aplicação | RCE validada via upload progress |
| FrankenPHP, LiteSpeed, php-cgi | Provável ou no escopo do aviso | Condicional |
As duas receberam CVSS v4.0 9.2:
Não é 10 porque explorar é complexo (falo disso mais abaixo). Mas, na prática, eu não daria importância pra essa diferença: é RCE sem autenticação, numa das linguagens mais usadas da web. E o ataque ainda vaza memória do servidor, o que pode expor sessões e senhas mesmo quando não chega a executar código. A exploração já foi confirmada, e a CISA colocou as duas no catálogo de vulnerabilidades exploradas ativamente.
Fake news e exageros
- "Vazaram os detalhes técnicos." Falso. Vazaram só os IDs das CVEs. O que ajudou atacantes foi o vídeo publicado por engano.
- "A falha derrubou a internet." Exagero. Os sites foram tirados do ar de propósito, por precaução, e não por ataque.
- "Afeta desde o PHP 5." Verdadeiro, segundo a watchTowr. Mas do 7.3 pra baixo não existe correção do PHP, só de distros e fornecedores de LTS.
- "Tem PR no GitHub corrigindo, é só aplicar." Cuidado. Os PRs de terceiros foram todos fechados sem merge. Não aplique patch de origem desconhecida em produção.
- "Saiu outra RCE crítica sem correção." Exagero. A CVE-2026-115560 exige uma configuração bem incomum, e o PHP vai corrigir no ciclo normal. Desligar o
session.upload_progress.enabledjá resolve.
Como o PHP corrigiu
Fui atrás do PR da correção e descobri que não existe PR público. Correções de segurança no PHP são feitas em privado e entram direto como commit no dia da release. Neste caso, foi o commit 3584a98, "Avoid state corruption via bailout", que fecha as duas CVEs.
E não é pequeno: são mais de 300 arquivos e cerca de 10,7 mil linhas adicionadas, boa parte testes simulando OOM em praticamente toda a biblioteca padrão. Na prática:
- o
longjmp()no OOM foi removido, e o PHP agora interrompe a execução num ponto seguro da VM; - os estados globais passaram a ser resetados antes da memória da requisição ser liberada.
A Foundation também anunciou mais gente no time de segurança, novas auditorias e decisões por maioria em vez de consenso, pra isso não travar de novo. E fez um pedido que eu reforço: se a sua empresa depende de PHP, vale olhar o programa de sponsors.
Como saber se estou vulnerável?
Você está protegido se estiver em uma destas versões ou superior:
| Branch | Versão corrigida |
|---|---|
| 8.5 | 8.5.12 |
| 8.4 | 8.4.27 |
| 8.3 | 8.3.36 |
| 8.2 | 8.2.35 |
| 7.4, 8.0 e 8.1 | Sem release, só branches de backport pra compilar: 7.4, 8.0 e 8.1 |
| 7.3 ou anterior | Sem correção do PHP, só via distro ou LTS |
Se você usa Debian ou Ubuntu com os pacotes do Ondřej Surý (ppa:ondrej/php ou deb.sury.org), ele já portou a correção pro 5.6, 7.4, 8.0 e 8.1, de graça. Pra 7.0 a 7.3, existem opções pagas, como Freexian, TuxCare e Ubuntu Pro (a Sansec reuniu a lista). Já a imagem Docker oficial php não recebe correção pra 8.1 ou anterior.
Pra conferir, crie um arquivo temporário no servidor, acesse pelo navegador (assim ele roda na mesma SAPI do site) e apague logo depois:
<?php
$fixed = ['8.6' => '8.6.0RC4', '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 'Versão: ', PHP_VERSION, ' | SAPI: ', PHP_SAPI, PHP_EOL;
if (!isset($fixed[$branch])) {
echo "Branch sem suporte: não existe release oficial com a correção", PHP_EOL;
} elseif (version_compare(PHP_VERSION, $fixed[$branch], '<')) {
echo "VULNERÁVEL: atualize para {$fixed[$branch]} ou superior", PHP_EOL;
} else {
echo "Versão com a correção", PHP_EOL;
}
Se SAPI vier como apache2handler, você está no mod_php, o cenário mais exposto. Pra varrer muitos sites de uma vez, a ProjectDiscovery publicou um template do Nuclei que só lê a versão no header, sem explorar nada.
Alguns cuidados:
- pacotes de distro (Debian, Ubuntu, RHEL) fazem backport sem mudar o número da versão. Consulte o aviso de segurança da sua distribuição;
- imagens Docker não se atualizam sozinhas: faça
docker pull, rebuild e deploy; - reinicie todos os workers depois de atualizar. Processo velho continua rodando o binário antigo;
- evite os "testes" que circulam no GitHub fazendo probe ativo. Muitos derrubam o worker de propósito. A versão e a SAPI já respondem se você está vulnerável.
E se eu já fui atacado?
Procure nos logs o Apache ou o PHP-FPM abrindo sh, curl ou wget, User-Agent com "php2shell" ou o número da CVE e picos de Allowed memory size exhausted. Encontrou algo? Trate como incidente, não só como atualização.
Não consigo atualizar agora, e aí?
O PHP publicou mitigações temporárias. Elas reduzem o risco, mas não resolvem:
; php.ini, pool do FPM ou config do servidor
session.upload_progress.enabled = 0
memory_limit = -1 ; via php_admin_value
post_max_size = 8M ; 32M se precisar de upload
upload_max_filesize = 2M
No PHP 8.5, defina também fatal_error_backtraces=0, limite o tamanho das requisições no Nginx ou Apache e reinicie todos os workers. Sim, memory_limit = -1 parece estranho, mas o exploit depende justamente de estourar esse limite de forma previsível. É paliativo, não solução.
Então o PHP acabou? Claro que não
Com tanta manchete, já apareceu gente dizendo que "é hora de largar o PHP". Calma.
Não é uma falha fácil de explorar. O exploit depende de layout de memória, do build e da quantidade de workers. A primeira RCE confirmada na internet foi num ambiente propositalmente favorável, com um único worker, e os PoCs que circularam antes da correção não funcionavam. Isso não é motivo pra relaxar, mas também não é um "qualquer um invade qualquer site PHP com um comando".
E não foi só o PHP. Na mesma semana, o Node.js corrigiu o Node2Shell (CVE-2026-111497), uma falha no decodificador Brotli que também permite execução remota de código. Express 5, Koa e o próprio fetch() descomprimem Brotli por padrão. E como o problema está na biblioteca do Google, ele também atingiu Bun, Python, .NET e outras ferramentas. Inclusive o próprio PHP no Windows, que ganhou builds novos por causa dela.
O que está acontecendo é maior que uma linguagem: a IA mudou o ritmo da segurança, pros dois lados. Ela está encontrando falhas antigas em todo o ecossistema (o PHP publicou 15 CVEs desde julho, e a falha do Node.js também foi reportada por uma ferramenta de IA) e acelerou a resposta: a Foundation passou a usar IA pra validar reports e exploits e agrupar os que têm a mesma causa raiz. Mas a correção continua sendo trabalho humano, nas palavras deles, "uma pessoa toma cada decisão e trabalha em cada patch". E a mesma IA gerou mais de 100 reports inválidos ou duplicados e está nas mãos de quem ataca.
Linguagem madura não é a que nunca tem falha, é a que corrige rápido e com transparência quando elas aparecem.
Manter atualizado não é opcional
Pra mim, essa é a principal lição. Quem estava numa branch suportada só precisou subir um patch. Quem está no 8.1 ou anterior ficou sem release: no máximo uma branch de backport pra compilar na mão ou o pacote de um mantenedor, e do 7.3 pra baixo, nem isso vindo do PHP. E não é pouca gente: a Mallory contou cerca de 884 mil servidores expostos nessa situação na véspera da correção.
O que vale pra qualquer time:
- esteja numa branch suportada. Se ainda está no 8.2, comece a migração agora;
- deixe o patch barato. Imagem versionada, testes automatizados e deploy simples transformam um patch de emergência em rotina;
- saiba o que roda em produção. Na hora do incidente, ninguém quer descobrir um servidor esquecido rodando mod_php.
Conclusão
O PHP2Shell foi sério: RCE sem autenticação, exploit confirmado e sites de governo fora do ar. E não dá pra ignorar que o problema era conhecido desde 2024.
Ao mesmo tempo, gostei da forma como a Foundation lidou com isso: assumiu o erro publicamente, explicou o que vai mudar e entregou uma correção que mexe de verdade na forma como o PHP lida com falta de memória. Isso é sinal de um projeto maduro.
A lição é a de sempre, mas continua valendo: atualize, e organize o seu ambiente pra que atualizar seja fácil da próxima vez.
Até a próxima e abraços! 🐘
Referências:
- The PHP Foundation: Today's PHP security release and how we're strengthening PHP security
- PHP.net: Security advisory, critical remote code execution vulnerabilities
- PHP.net: Informational advisory, session upload progress
- Commit da correção no php-src
- watchTowr: PHP2Shell FAQ
- CISA: Critical vulnerabilities in PHP require immediate patching
- g1: O que é PHP e a falha grave de segurança detectada por IA que tirou sites do ar
- g1: Brecha no PHP que tirou sites do ar foi descoberta há dois anos
- Times Brasil: Falha de segurança tira páginas de governos do ar e leva NSA a alertar empresas
- FBI Cyber Division: alerta sobre as vulnerabilidades no PHP
- Newsweek: FBI issues advice as security issue hits global websites
- Akamai: Inside Node2Shell, a closer look at CVE-2026-111497
- The Hacker News: Brotli decoder flaw behind Node.js RCE also affects Bun, Python and other software
- Sansec: PHP2Shell, correções pra versões sem suporte
- ProjectDiscovery: PHP2Shell, finding and patching affected PHP