Acordou, checou o Hacker News e quase derrubou o café
Se você é dev PHP (ou mantém qualquer servidor que roda PHP), o dia 21 de outubro de 2026 entrou pra história. Duas vulnerabilidades críticas no core do PHP, batizadas de PHP2Shell, ganharam patches de emergência depois que um exploit vazou antes da hora e atacantes já estavam explorando servidores ao redor do mundo. O nome não é exagero: um único POST HTTP é o suficiente para ganhar shell no seu servidor.
Vamos direto ao que importa: o que são essas falhas, como funcionam, quem está em risco e o que você precisa fazer agora.
O que é o PHP2Shell
PHP2Shell é o nome dado ao exploit que explora duas vulnerabilidades de execução remota de código (RCE) no interpretador PHP:
| CVE | CVSS v4.0 | Tipo |
|---|---|---|
| CVE-2026-109618 | 9.2 (Crítico) | RCE não autenticado |
| CVE-2026-109619 | 9.2 (Crítico) | RCE não autenticado |
O ponto crucial: essas falhas não estão em nenhum framework, plugin ou biblioteca. Estão no próprio PHP. Isso significa que não importa se você roda WordPress, Laravel, Drupal, Magento, Joomla ou aquele sistema legado que ninguém tem coragem de mexer. Se o servidor responde requisições PHP, ele é vulnerável.
Como o exploit funciona (a parte técnica)
Aqui é onde a coisa fica feia de verdade. O PHP, antes de executar qualquer linha do seu código, faz o parsing das requisições HTTP. Quando você envia um POST com Content-Type: multipart/form-data, o interpretador processa o corpo da requisição automaticamente, incluindo o gerenciamento de progresso de uploads via session.upload_progress.
As duas CVEs exploram primitivas de use-after-free no heap dentro desse processamento:
- CVE-2026-109618: explora o handler de
session.upload_progress, que faz bookkeeping de uploads em andamento - CVE-2026-109619: explora o próprio parser de
multipart/form-data, que roda para qualquer POST multipart, independente de upload progress estar habilitado
POST /qualquer-script.php HTTP/1.1
Content-Type: multipart/form-data; boundary=----exploit
Content-Length: ...
------exploit
Content-Disposition: form-data; name="PHP_SESSION_UPLOAD_PROGRESS"
[payload crafted para triggerar use-after-free]
------exploit--
O atacante envia uma requisição multipart cuidadosamente construída. O PHP processa essa requisição antes de qualquer middleware, firewall de aplicação ou autenticação entrar em cena. O use-after-free permite controlar a execução e, pronto: shell no servidor.
Eu já vi muita CVE crítica, mas poucas com esse nível de superfície de ataque. Qualquer script PHP exposto na internet serve como ponto de entrada. Não precisa de login, não precisa de formulário de upload, não precisa de nada. Só um POST.
A timeline do desastre
A sequência de eventos parece saída de um thriller de cibersegurança:
| Data/Hora (UTC) | Evento |
|---|---|
| 20/out, manhã | Screenshots do exploit PHP2Shell (creditado a Calif.IO) vazam no Hacker News |
| 20/out, tarde | Pesquisadores da watchTowr confirmam que as vulnerabilidades são reais e reproduzem a CVE-2026-109618 |
| 20/out, noite | PHP Foundation antecipa o release em 24 horas |
| 21/out, 07:43 | Primeiros ataques detectados in-the-wild, antes do patch sair |
| 21/out, 14:00 | Patches oficiais liberados |
| 21/out, 14:15 | Exploração em massa esperada e confirmada |
Percebe o problema? O exploit vazou um dia inteiro antes do patch. E os primeiros ataques aconteceram mais de 6 horas antes da correção ser publicada. Quem não estava monitorando de perto ficou exposto por horas.
Versões afetadas e corrigidas
Aqui entra a parte que vai tirar o sono de muita gente:
| Branch PHP | Versão corrigida | Status |
|---|---|---|
| PHP 8.5 | 8.5.12 | Corrigido |
| PHP 8.4 | 8.4.27 | Corrigido |
| PHP 8.3 | 8.3.36 | Corrigido |
| PHP 8.2 | 8.2.35 | Corrigido |
| PHP 8.1 e anteriores | Sem patch | End of Life |
A PHP Foundation só libera patches para branches com suporte ativo. Se você roda PHP 8.1, 8.0, 7.x ou (Deus me livre) PHP 5.x: não vai ter correção oficial.
E aqui vem o número que dói: pesquisadores estimam que 884 mil hosts rodando versões end-of-life nunca vão receber esse patch. São quase um milhão de servidores permanentemente vulneráveis. Muitos deles são aquele e-commerce de PME que “está funcionando, não mexe”, aquele blog WordPress esquecido ou aquele painel administrativo legado que ninguém quer migrar.
WordPress, Laravel, Drupal: todo mundo na mira
Vou ser direto: se o seu site roda em PHP, ele era vulnerável. Não interessa o framework.
- WordPress: 43% da web roda WordPress. Todo WordPress roda PHP. Faça as contas.
- Laravel: seu
artisan serveou PHP-FPM atrás do nginx? Vulnerável. - Drupal: mesma situação.
- Magento/WooCommerce: lojas online processando pagamentos. Com shell no servidor, o atacante tem acesso a tudo.
- APIs em PHP: aquele microserviço que “é só uma API simples” também aceita POST multipart.
A falha está no runtime, não no seu código. Você pode ter 100% de cobertura de testes, usar OWASP top 10 como checklist diário, rodar SAST/DAST no pipeline. Nada disso ajuda quando o buraco está no interpretador.
Como verificar se você está vulnerável
Primeiro passo: descubra qual PHP está rodando.
# No servidor
php -v
# Via phpinfo (crie um arquivo temporário, delete depois!)
echo "<?php phpinfo(); ?>" > /tmp/check.php
php /tmp/check.php | grep "PHP Version"
rm /tmp/check.php
# Checar TODOS os binários PHP no sistema
find / -name "php" -o -name "php-fpm" -o -name "php-cgi" 2>/dev/null | while read bin; do
echo "$bin: $($bin -v 2>/dev/null | head -1)"
done
Se a versão for menor que 8.2.35, 8.3.36, 8.4.27 ou 8.5.12, você precisa atualizar agora. Não amanhã, não na próxima sprint, não no próximo deploy agendado. Agora.
Para ambientes com Docker:
# Checar imagens PHP em uso
docker images | grep php
docker ps --format '{{.Names}} {{.Image}}' | grep php
# Atualizar imagem base
docker pull php:8.4-fpm
docker pull php:8.3-fpm
# Rebuild e redeploy
Para quem usa gerenciadores de pacotes:
# Debian/Ubuntu
sudo apt update && sudo apt upgrade php*
# CentOS/RHEL (com Remi repo)
sudo dnf update php*
# macOS (Homebrew)
brew update && brew upgrade php
Mitigações temporárias (se não pode atualizar agora)
Atualizar é a única solução real. Mas se você precisa de tempo para testar o patch antes de aplicar em produção, existem mitigações parciais:
1. Desabilitar upload progress no php.ini:
; /etc/php/8.x/fpm/php.ini
session.upload_progress.enabled = Off
session.use_strict_mode = On
Isso mitiga a CVE-2026-109618, mas não a CVE-2026-109619, que afeta o parser multipart diretamente.
2. Bloquear requisições multipart no web server:
# nginx - bloquear multipart/form-data globalmente
# CUIDADO: isso quebra uploads e formulários!
if ($content_type ~* "multipart/form-data") {
return 403;
}
# Apache - mesmo efeito
RewriteEngine On
RewriteCond %{CONTENT_TYPE} multipart/form-data [NC]
RewriteRule .* - [F,L]
Obviamente, bloquear multipart/form-data vai quebrar qualquer formulário que faça upload de arquivos. É uma medida de emergência, não uma solução.
3. WAF rules (Cloudflare, AWS WAF, etc.):
Se você usa Cloudflare, crie uma regra customizada para bloquear POSTs multipart em endpoints que não precisam de upload. Isso reduz a superfície sem quebrar tudo.
4. Isolar servidores PHP antigos:
Se você tem servidores rodando PHP 7.x ou 8.1 que não vão receber patch, a melhor opção é tirá-los da internet. Coloque atrás de uma VPN, restrinja o acesso por IP ou, melhor ainda, comece a planejar a migração.
Como detectar se você já foi comprometido
Se o seu servidor estava exposto entre 20 e 21 de outubro (ou se roda uma versão sem patch), vale fazer uma varredura:
# Procurar processos suspeitos spawned por PHP
ps aux | grep -E "(php|php-fpm)" | grep -v grep
# Checar se PHP spawnou shells
find /var/log -name "*.log" -newer /tmp/check_date -exec grep -l "sh\|bash\|wget\|curl\|nc " {} \;
# Procurar webshells comuns
find /var/www -name "*.php" -newer /tmp/check_date -exec grep -lE "(eval\(|base64_decode\(|system\(|exec\(|passthru\()" {} \;
# Checar crontabs novos
crontab -l
ls -la /etc/cron.d/
Indicadores de comprometimento incluem:
- Processos filhos de PHP executando
sh,bash,cmd.exeoupowershell.exe - Uso de
curl,wget,nca partir do contexto do PHP - Padrões de reverse shell:
/dev/tcp/,fsockopen,mkfifo - Comandos de reconhecimento:
whoami,id,uname -a - Novos arquivos .php em diretórios de upload ou temporários
Se encontrar qualquer sinal, preserve os logs antes de tudo. Depois isole o servidor, identifique o vetor de entrada e faça a análise forense. Não limpe e siga em frente, porque o atacante pode ter deixado backdoors que você ainda não encontrou.
O problema dos 884 mil servidores sem patch
Esse é o elefante na sala que pouca gente está discutindo. Quase um milhão de servidores PHP rodando versões end-of-life vão permanecer vulneráveis indefinidamente. E a maioria desses servidores não tem um sysadmin dedicado monitorando CVEs.
São hospedagens compartilhadas com dezenas de sites cada. São VPSs contratadas em 2019 e esquecidas. São aqueles projetos “temporários” que viraram permanentes. São ERPs internos rodando PHP 7.2 que “custam muito caro pra migrar”.
Para esses casos, a comunidade open source já começou a se mobilizar. O projeto php2shell-protection no GitHub oferece regras de mitigação para Apache que bloqueiam requisições multipart antes de chegarem ao PHP. Não é um patch, mas é melhor que nada.
Alguns provedores de hospedagem maiores (como Cloudways e SiteGround) já forçaram atualizações automáticas. Mas hospedagens menores e servidores auto-gerenciados vão depender de quem administra se dar conta do problema.
Por que isso aconteceu: o parsing que ninguém auditava
Uma reflexão que vale a pena fazer: como um bug no parsing de multipart/form-data sobreviveu desde o PHP 5.4 (lançado em 2012) até 2026? São 14 anos.
A resposta é que essa parte do código do PHP é uma das mais antigas e menos auditadas. O parsing de requisições HTTP é tão fundamental que todo mundo assume que “já foi resolvido”. É infraestrutura invisível. Ninguém escreve testes para o parser de multipart do runtime, porque isso “não é responsabilidade do desenvolvedor da aplicação”.
Só que é responsabilidade de alguém. E durante 14 anos, essas primitivas de use-after-free ficaram ali, esperando. O código do session.upload_progress foi adicionado no PHP 5.4 para permitir que desenvolvedores mostrassem barras de progresso de upload sem precisar de extensões externas. Uma feature de conveniência que virou um vetor de ataque crítico.
Isso me lembra do Heartbleed, do Log4Shell e de tantas outras vulnerabilidades em componentes que “todo mundo usa mas ninguém olha”. A diferença é que o PHP roda em mais de 75% dos sites com server-side scripting identificável. A superfície de ataque é absurda.
Checklist de emergência
Para facilitar, aqui vai um checklist direto:
- • Identificar TODAS as instâncias PHP no seu ambiente (servidores, containers, lambdas, shared hosting)
- • Verificar a versão de cada uma com
php -v - • Atualizar para 8.2.35, 8.3.36, 8.4.27 ou 8.5.12 (conforme o branch)
- • Se não puder atualizar imediatamente: aplicar mitigações temporárias (desabilitar upload progress + WAF rules)
- • Se roda PHP 8.1 ou anterior: planejar migração urgente ou isolar da internet
- • Verificar logs em busca de sinais de comprometimento entre 20 e 21 de outubro
- • Procurar webshells e backdoors em diretórios web
- • Notificar a equipe de segurança e documentar as ações tomadas
- • Monitorar advisories do PHP nos próximos dias para detalhes adicionais
O que esperar nos próximos dias
Com o exploit público e o patch disponível, a corrida agora é entre quem atualiza e quem explora. A experiência com vulnerabilidades similares (como a CVE-2024-4577, também em PHP/CGI) mostra que bots automatizados começam a escanear a internet inteira em questão de horas após o patch sair. Quem não atualizou até agora já está em risco elevado.
Espere também um aumento de webshells aparecendo em sites comprometidos, campanhas de ransomware mirando servidores PHP desatualizados e, infelizmente, supply chain attacks usando sites legítimos comprometidos como distribuição de malware.
Se você mantém servidores PHP, esse é o tipo de vulnerabilidade que justifica parar tudo e atualizar. Não é hyperbole. CVSS 9.2, RCE não autenticado, exploit público, ataques confirmados. Prioridade máxima.
Fonte de inspiração: Upcoming critical PHP security release, php.net e PHP2Shell: Critical PHP RCE, Sansec













