DEV Community

Cover image for PHP2Shell: falha no PHP permite que qualquer pessoa execute código no seu servidor (corrija agora)
Lucas
Lucas

Posted on Originally published at apidog.com

PHP2Shell: falha no PHP permite que qualquer pessoa execute código no seu servidor (corrija agora)

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.

Experimente o Apidog hoje

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
Enter fullscreen mode Exit fullscreen mode

Ou exponha isso uma vez em uma rota protegida e remova depois:

<?php echo PHP_VERSION, ' ', PHP_SAPI;
Enter fullscreen mode Exit fullscreen mode

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 ros 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.

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](https://bleepingcomputer.com/news/security/php-ships-emergency-patches-for-critical-php2shell-flaws) que nenhuma mitigação bloqueia totalmente os ataques.

**Para o CVE-2026-109618:**

- Defina `memory_limit=-1` onde os apps não possam sobrescrever (`php_admin_value` no 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_size` no nginx), e defina limites de memória de contêiner ou cgroup como fronteira de disponibilidade.
- Não use limites de processo `RLIMIT_AS` ou `RLIMIT_DATA`. Eles podem causar justamente as falhas de alocação que o exploit precisa.

**Para o CVE-2026-109619:**

- Defina `session.upload_progress.enabled=0` em 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=0` ou `@` 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 exhausted` com `Unknown 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](https://apidog.com/apidog-cli/?utm_source=dev.to&utm_medium=wanda&utm_content=n8n-post-automation).

**Configuração (uma vez):**

Enter fullscreen mode Exit fullscreen mode


bash
npm install -g apidog-cli
apidog auth login --with-token
apidog test-suite list --project


**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:**

Enter fullscreen mode Exit fullscreen mode


bash
apidog test-suite run --project -e

apidog run --test-suite --project -e \
-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](https://apidog.com/pt/blog/apidog-cli-in-claude-code/?utm_source=dev.to&utm_medium=wanda&utm_content=n8n-post-automation) e o [tutorial do pipeline de CI/CD](https://apidog.com/pt/blog/apidog-cli-ci-cd-pipeline/?utm_source=dev.to&utm_medium=wanda&utm_content=n8n-post-automation) 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](https://apidog.com/download/?utm_source=dev.to&utm_medium=wanda&utm_content=n8n-post-automation) 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.

  

Enter fullscreen mode Exit fullscreen mode

Top comments (0)