O PHP2Shell são duas vulnerabilidades críticas no próprio PHP, CVE-2026-109618 e CVE-2026-109619, que podem permitir que um pedido web sem autenticação execute código em qualquer instalação PHP que sirva pedidos web: PHP-FPM, Apache com mod_php, php-cgi, FrankenPHP e LiteSpeed. Ambas são exploradas em ambiente real e constam do catálogo KEV da CISA. A correção é o PHP 8.5.12, 8.4.27, 8.3.36 ou 8.2.35; o PHP 8.1 e anteriores não recebem nenhuma versão upstream. Atualize e, em seguida, reconstrua e reimplemente todas as imagens de contentor que incluem PHP, incluindo tags antigas ainda em execução e imagens que entregou a clientes.
Corrigir o servidor que conhece é a parte fácil. A exposição que perdura é o PHP de que se esqueceu: um runtime compilado numa imagem base, uma tag de imagem do ano passado que ainda corre em produção, uma imagem de CI ou um produto entregue a clientes com um PHP em fim de vida. Esta página ajuda-o primeiro a corrigir e depois mostra como encontrar o resto.
O que aconteceu
| Data (2026) | Acontecimento | Fonte |
|---|---|---|
| 11 e 21 de agosto | A Calif comunica os dois erros ao projeto PHP | Calif |
| 17 de outubro | A primeira tentativa de exploração que a Amazon viu nos seus honeypots, antes da divulgação | Amazon Threat Intelligence |
| 20 de outubro | O PHP anuncia uma versão de segurança para 21 de outubro, às 14:00 UTC, que corrige duas vulnerabilidades classificadas com 9,2 em CVSS 4.0 | php.net |
| 21 de outubro | O PHP lança as versões 8.5.12, 8.4.27, 8.3.36 e 8.2.35 e publica o seu aviso de segurança; os registos CVE tornam-se públicos; o NCSC-NL abre o seu repositório php2shell | Aviso do PHP, NCSC-NL |
| 21 de outubro | As imagens Docker oficiais php são atualizadas para as versões corrigidas | docker-library/php |
| 21 de outubro | A watchTowr comunica a exploração de ambas as CVE em ambiente real; a CISA publica um alerta | watchTowr, CISA |
| 22 de outubro | A Searchlight Cyber publica o php2shell-scanner | GitHub |
| 23 de outubro | O PHP aconselha definir session.upload_progress.enabled=0 para um vetor de RCE distinto e pouco provável, CVE-2026-115560 | php.net |
| 26 de outubro | A CISA adiciona ambas as CVE ao catálogo KEV, com prazo até 29 de outubro para as agências federais dos EUA | CISA KEV |
O nome PHP2Shell vem da análise publicada pela Calif e é usado em toda a cobertura do setor; os avisos de segurança do próprio PHP não o usam. Os registos CVE atribuem a descoberta à Calif, à Wiz e à OpenAI.
Quem é afetado
Qualquer PHP que sirva pedidos web. O aviso de segurança do PHP refere PHP-FPM, Apache com mod_php, php-cgi, FrankenPHP e LiteSpeed, e considera o risco mais elevado para o mod_php, "com um exploit demonstrado em que um pedido sem autenticação pode desencadear o ataque antes de ser executado qualquer código da aplicação". Como os erros estão no próprio PHP, as aplicações construídas com Laravel, Symfony ou WordPress ficam expostas sempre que o PHP por baixo delas o está.
| Ramo | Afetado | Corrigido em | Suporte upstream |
|---|---|---|---|
| 8.5 | antes de 8.5.12 | 8.5.12 | Ativo |
| 8.4 | antes de 8.4.27 | 8.4.27 | Ativo |
| 8.3 | antes de 8.3.36 | 8.3.36 | Apenas correções de segurança, até 31 de dezembro de 2027 |
| 8.2 | antes de 8.2.35 | 8.2.35 | Apenas correções de segurança, até 31 de dezembro de 2026 |
| 8.1, 8.0, 7.4 | todas as versões, segundo a Calif e a watchTowr | sem versão; backports mínimos do código-fonte no php-src | Fim de vida |
| 7.3 e anteriores, incluindo o PHP 5 | todas as versões, segundo a Calif e a watchTowr | sem correção upstream | Fim de vida |
Os avisos de segurança do PHP listam apenas os ramos suportados. Para os mais antigos, a Calif indica que "o caminho afetado mais antigo que encontrámos remonta ao PHP 5.4.0", e a watchTowr lista o PHP 7 e o PHP 5 como afetados e sem correção. O PHP afirma que os ramos 8.1 e anteriores "já não recebem atualizações do projeto PHP", mas publicou backports mínimos do código-fonte para 7.4, 8.0 e 8.1 para quem compila a partir do código-fonte. Algumas distribuições e fornecedores comerciais de suporte de longo prazo disponibilizam correções retroportadas para ramos em fim de vida; consulte o seu. Se estiver a testar a próxima versão principal, o PHP 8.6.0 RC4, lançado no mesmo dia, também contém as correções.
Como funciona
Ambas as CVE são erros de segurança de memória na forma como o PHP prepara e encerra um pedido, abaixo de qualquer código da aplicação. Os registos CVE classificam ambas como use after free (CWE-416), juntamente com tratamento incorreto de condições excecionais, acesso a um ponteiro não inicializado, alocação de memória não controlada e inicialização incorreta (CWE-755, CWE-824, CWE-1325, CWE-1419). Nas palavras do PHP:
- CVE-2026-109618, RCE através de corrupção por falta de memória (OOM): "o tratamento de falta de memória pode interromper o PHP enquanto os dados internos do pedido estão apenas parcialmente inicializados. A limpeza do pedido pode então tratar os dados inválidos como válidos." Um corpo de pedido construído para esgotar a memória enquanto o PHP o analisa pode provocar essa saída. O Apache com mod_php executa a limpeza mesmo quando o arranque do pedido falhou, e é por isso que aí o ataque funciona antes de qualquer código da aplicação ser executado. Para o PHP-FPM, o aviso do PHP indica que a análise do código-fonte sustenta que é suscetível, embora não tenha sido demonstrado nenhum exploit completo para FPM.
- CVE-2026-109619, RCE através de estado global obsoleto: "o estado interno pertencente a um pedido pode sobreviver depois de a memória que o suporta ter sido libertada. Um pedido posterior tratado pelo mesmo worker pode usar esse estado obsoleto antes de a inicialização normal o repor." São necessários dois pedidos que cheguem ao mesmo worker: um que deixa o estado para trás, por exemplo através de um erro fatal, e outro que o utiliza. O aviso do PHP confirma a via do progresso de carregamento da sessão contra o mod_php e o FPM, e a via dos backtraces de erros fatais do PHP 8.5 contra o mod_php.
É por isso que as definições provisórias do PHP visam os limites de memória, o tamanho do corpo do pedido, o progresso de carregamento da sessão e os backtraces de erros fatais: cada uma fecha uma via para os erros, não os erros em si. O PHP, enquanto CNA, classifica ambas com 9,2 em CVSS 4.0. As avaliações CVSS 3.1 do próprio NVD são de 9,8 para a CVE-2026-109618 e de 8,1 para a CVE-2026-109619.
Como verificar se foi afetado
Comece pelos hosts que conhece e depois procure PHP em tudo o que constrói e entrega.
Num host ou VM, verifique a versão que o PHP indica. Verifique também a SAPI web, já que o php-fpm ou o módulo do Apache podem provir de um pacote diferente do da linha de comandos:
php -v
php-fpm -v
Os pacotes das distribuições (Debian, Ubuntu, Alpine, RHEL) recebem muitas vezes a correção como backport, sem uma nova versão upstream: o Ubuntu 24.04, por exemplo, disponibiliza a correção como 8.3.6-0ubuntu0.24.04.13. Aqui, uma verificação da versão por si só induz em erro. Liste o pacote instalado e compare-o com a versão corrigida do pacote no rastreador de segurança da sua distribuição:
dpkg -l 'php*' | grep '^ii' # Debian, Ubuntu
apk info -v | grep '^php' # Alpine
rpm -qa 'php*' # RHEL, Fedora, Rocky, Alma
Em imagens de contentor. As imagens oficiais php: compilam o PHP a partir do código-fonte, pelo que a versão está na própria imagem e não numa lista de pacotes da distribuição. Pergunte diretamente à imagem:
docker run --rm --entrypoint php php:8.3-fpm -v
Para verificar todas as imagens que realmente executa, liste-as e pergunte a cada uma. Para Kubernetes:
kubectl get pods -A \
-o jsonpath='{range .items[*]}{range .spec.containers[*]}{.image}{"\n"}{end}{end}' \
| sort -u \
| while read -r image; do
version=$(docker run --rm --entrypoint php "$image" -r 'echo PHP_VERSION;' 2>/dev/null)
printf '%s\t%s\n' "${version:-no php}" "$image"
done
As imagens construídas FROM debian ou FROM alpine com o PHP instalado pelo gestor de pacotes precisam da verificação de pacotes acima, executada dentro da imagem.
Nos seus repositórios, procure todos os sítios onde o PHP é escolhido:
git grep -nE '^FROM[[:space:]]+(.*/)?php:' -- '*Dockerfile*' '*.dockerfile'
git grep -nE 'php-version|image:.*php' -- .github/workflows '*.yml' '*.yaml'
As tags fixas, como php:8.3.30-fpm, continuam vulneráveis até alguém as alterar. As tags flutuantes, como php:8.3-fpm, foram reconstruídas com as versões corrigidas a partir de 21 de outubro, mas uma imagem construída antes disso mantém o PHP antigo até a reconstruir. A restrição php em composer.json diz que versões o seu código aceita, não qual delas está em execução.
Na CI. Os jobs de build e de teste usam muitas vezes o seu próprio PHP: um contentor de serviço php:, uma action de configuração com um input php-version ou uma imagem de runner. Não servem tráfego de produção, mas mostram que imagens e versões o seu pipeline produz.
Hosts expostos. O php2shell-scanner da Searchlight Cyber testa um URL com grandes pedidos multipart, cerca de 29 MiB por caminho. Execute-o apenas contra hosts que esteja autorizado a testar. O seu README alerta para falsos positivos em PHP corrigido com um memory_limit baixo e, quando o PHP não divulga a sua versão, o scanner não consegue distinguir um servidor corrigido de um vulnerável. Trate-o como uma pista, não como prova. O repositório do NCSC-NL reúne regras de deteção e uma lista de produtos que incluem PHP, com o respetivo estado.
O que a análise de hoje não lhe diz. Analisar hoje as imagens do seu registo cobre o que implementaria hoje. Não cobre uma versão anterior que entregou a um cliente, a tag antiga que um cliente ainda executa, nem quais dos seus builds produziram imagens com um PHP vulnerável. Para isso precisa de um registo do que cada build incluiu, por versão. Consulte fomos afetados? como avaliar uma nova CVE em todos os seus builds.
Como corrigir, e o que fazer se ainda não puder aplicar o patch
- Atualize para 8.5.12, 8.4.27, 8.3.36 ou 8.2.35, ou para o pacote corrigido da sua distribuição. No 8.1 ou anteriores, passe para um ramo suportado; os backports do PHP e os builds dos fornecedores são soluções provisórias.
- Reconstrua todas as imagens a partir de uma base corrigida (volte a obter a imagem base ou faça o build sem cache) e reimplemente. As imagens já em execução mantêm o PHP antigo até serem substituídas, por isso reinicie também as cargas de trabalho.
- Verifique com a lista de verificação abaixo, contra os contentores em execução, e não apenas contra a nova imagem.
Se ainda não puder atualizar, o aviso de segurança do PHP lista medidas que "reduzem a exposição a vias de ataque específicas, mas não tornam uma instalação segura". Para a CVE-2026-109618:
- "Defina
memory_limit=-1, de preferência de forma que as aplicações não o possam substituir, comophp_admin_valueno pool FPM ou na configuração do Apache, e verifique que nenhuma definição de pool, diretório ou aplicação volta a impor um limite finito." - "Para aplicações que não precisam de carregamento de ficheiros, defina
post_max_size = 8M. Se o carregamento de ficheiros for necessário, definapost_max_size = 32M. Mantenhaupload_max_filesizeabaixo depost_max_size." - Use um limite de memória do contentor ou do cgroup como limite de disponibilidade e não o substitua por
RLIMIT_ASnem porRLIMIT_DATA, "pois estes podem causar a falha de alocação vulnerável".
Para a CVE-2026-109619:
- "Defina
session.upload_progress.enabled=0e reinicie todos os workers. Use ophp.ini, um pool FPM ou uma configuração do servidor que se aplique antes da análise do pedido. Não dependa deini_set()nem do.user.inido FPM." - "No PHP 8.5, defina
fatal_error_backtraces=0e reinicie todos os workers."
Verifique com que definições cada worker está realmente a correr:
php-fpm -i | grep -E 'memory_limit|post_max_size|session.upload_progress.enabled'
O alerta da CISA vai mais longe: as organizações que não possam atualizar de imediato, ou que ainda executem o PHP 8.1 ou anterior, "devem desligar os sistemas baseados em PHP até poderem ser corrigidos ou atualizados". Aconselha também a vigiar processos worker do PHP que lancem shells ou descarreguem ferramentas.
Verificar a correção
- Pergunte ao PHP em execução, não à imagem que pretendia implementar. Execute
php-fpm -v(ouphp -v) dentro de cada contentor em execução e em cada host, e confirme 8.5.12, 8.4.27, 8.3.36, 8.2.35 ou posterior. - Não confie apenas na string de versão nos pacotes das distribuições. O Debian, o Ubuntu, o RHEL e outras distribuições aplicam a correção como backport na versão que já disponibilizam, pelo que um PHP corrigido pode continuar a indicar 8.3.6: a correção do Ubuntu 24.04 é
8.3.6-0ubuntu0.24.04.13. Compare a versão completa do pacote com o rastreador de segurança da sua distribuição, ou procure a CVE no changelog do pacote, que normalmente a menciona. A armadilha também funciona ao contrário: um scanner que compare apenas números de versão upstream pode assinalar como vulnerável um pacote com backport. - Confirme que todas as cargas de trabalho executam a imagem reconstruída. Uma tag que agora aponta para uma imagem corrigida não altera um pod que obteve a antiga. Compare o digest da imagem que cada contentor executa com o digest que construiu:
kubectl get pods -A \
-o jsonpath='{range .items[*]}{range .status.containerStatuses[*]}{.image}{"\t"}{.imageID}{"\n"}{end}{end}'
- Confirme que todos os workers foram reiniciados. O PHP-FPM e o Apache mantêm o código antigo carregado até reiniciarem; a verificação de processos em "Verificar se houve comprometimento" mostra os que ainda o executam.
- Se ainda depende das definições provisórias, verifique cada pool com o comando
php-fpm -iacima e mantenha-as até a atualização estar concluída em todo o lado. - Volte a fazer o inventário da secção de verificação no seu registo, nas imagens de CI e nas versões que os clientes executam, e não apenas em produção.
Verificar se houve comprometimento
O PHP2Shell é explorado em ambiente real, e a Amazon detetou a primeira tentativa a 17 de outubro de 2026, quatro dias antes da correção. Se um PHP exposto à internet executou uma versão afetada sem as definições provisórias em qualquer momento desde então, verifique-o.
A dimensão da exposição. As contagens de banners do Shodan que a Mallory publicou a 20 de outubro, citadas pela CybelAngel, encontraram 2,24 milhões de hosts expostos à internet que anunciam PHP; dos cerca de 1,5 milhões que mostram uma versão, 883 717 (59%) executam um ramo sem correção oficial. Estes números contam hosts, não sistemas vulneráveis confirmados: os pacotes com backport podem parecer antigos e estar corrigidos, e cerca de 740 000 hosts ocultam a sua versão.
Appliances e produtos que incluem PHP. O PHP também é executado dentro de appliances, dispositivos de rede, interfaces de gestão e produtos de fornecedores em que talvez não o possa atualizar por si. O inventário do NCSC-NL registava 968 produtos deste tipo a 9 de novembro de 2026: 205 corrigidos, 215 vulneráveis, 93 em investigação, 240 dependentes do runtime e 214 não afetados. Verifique esses produtos separadamente e aplique as atualizações dos fornecedores assim que estiverem disponíveis.
Confirme que a correção está mesmo em execução. Em hosts e VMs, um processo PHP-FPM, php-cgi ou Apache que arrancou antes da atualização continua a executar o código antigo. O seu mapa de memória mostra então o binário substituído ou a libphp como eliminados. Compare também as horas de arranque dos processos com a hora da atualização:
for pid in $(pgrep -f 'php-fpm|php-cgi|apache2|httpd|frankenphp'); do
grep -qE '(php|libphp)[^/]*\(deleted\)' "/proc/$pid/maps" 2>/dev/null \
&& echo "PID $pid still runs a replaced PHP"
done
ps -o pid,lstart,args -p "$(pgrep -d, -f 'php-fpm|php-cgi|apache2|httpd|frankenphp')"
Indicadores de fontes primárias:
- Pedidos: pedidos POST de carregamento de formulários que contêm a string
PHP_SESSION_UPLOAD_PROGRESS, que a Amazon Threat Intelligence detetou em tentativas de exploração. A Amazon lista também endereços de origem (103.216.220.92,31.223.184.166,37.19.200.5,134.209.159.64,103.114.163.188,95.217.98.37), mas observa que pertencem a infraestrutura de anonimização partilhada: investigue uma correspondência, não a trate como prova. - Processos e ficheiros: processos worker do PHP que lançam shells ou descarregam ferramentas (CISA, que acrescentou uma regra de deteção Sigma a 23 de outubro), e execução de processos ou alterações de ficheiros inesperadas em servidores web (Amazon).
- Logs: nos logs do Apache, do PHP-FPM, de reverse proxies e de serviços, avisos ou erros do núcleo repetidos antes da execução dos scripts, erros fatais e de análise, e
Maximum execution time exceeded. O aviso do PHP acrescenta que "a ausência de um erro nos logs não é prova de segurança."
Quando presumir o comprometimento. Se encontrar qualquer um destes indicadores, ou se um servidor exposto executou um PHP afetado sem mitigações e os seus logs não permitem excluir a exploração, trate-o como comprometido. O PHP descreve o impacto como execução remota de código com a conta do worker web, e essa conta normalmente pode ler a configuração e os segredos da aplicação.
Faça a rotação do que o worker podia ler. Palavras-passe de bases de dados, chaves de API e tokens em variáveis de ambiente e ficheiros de configuração, chaves que assinam sessões ou cookies (e as sessões assinadas com elas), e quaisquer credenciais cloud disponíveis no host. Faça a rotação depois de reconstruir o host, para que os novos segredos nunca fiquem numa máquina comprometida.
Reconstrua em vez de limpar. Substitua um host ou contentor comprometido a partir de uma imagem de confiança, e não transfira ficheiros em que o worker podia escrever, como diretórios de carregamento, caches ou código gerado. Não reutilize imagens, caches de build nem artefactos produzidos num host comprometido.
O que dizer aos seus clientes
Se entrega software que corre em PHP, os seus clientes vão perguntar. Responda com versões e ações, mesmo antes de ter todas as respostas. Uma resposta que pode adaptar:
O PHP2Shell (CVE-2026-109618, CVE-2026-109619) afeta as versões do PHP anteriores a 8.5.12, 8.4.27, 8.3.36 e 8.2.35, bem como todos os ramos mais antigos do PHP. As versões [x a y] do [Produto] incluem o PHP [versão] e são afetadas; a versão [z], lançada a [data], inclui o PHP [versão corrigida]. Atualize para a [z]. Se não puder atualizar de imediato, aplique as definições do PHP indicadas no nosso aviso de segurança [ligação] e limite o acesso de rede à aplicação. As versões [a a b] do [Produto] não são afetadas. Atualizaremos este aviso até [data].
Se ainda estiver a verificar, diga-o, e diga quando vai responder. Para uma primeira declaração e modelos para cada resultado, consulte como responder aos clientes após um ataque à cadeia de abastecimento.
Como o CRACI ajuda
O CRACI executa os seus jobs de GitHub Actions e regista o que cada job obtém durante o build, incluindo imagens de contentor, pacotes apt e apk e pacotes Composer, e guarda todos os builds anteriores com a respetiva SBOM. Quando é publicada uma CVE, a reavaliação contínua assinala os builds anteriores que continham o pacote afetado, para que veja que versões estiveram expostas e durante quanto tempo, e não apenas o que a análise de hoje encontra. Os policy gates podem travar builds que contenham uma CVE específica.
Um limite neste incidente: o PHP compilado numa imagem oficial php: chega dentro da imagem, não como descarga de um pacote. O CRACI regista a referência de imagem que cada build obteve, por isso procure nos seus builds as tags php: e também os pacotes PHP.
Encontre todos os builds que entregaram um PHP vulnerável
Mais sobre registos de build: SBOM no momento do build, SBOM de imagens Docker, o que a análise de contentores não deteta, o catálogo KEV da CISA e tendências de publicação de CVE. Outros incidentes: todas as vulnerabilidades.
Para a segurança de PHP para além deste incidente, consulte o nosso guia de segurança de PHP.
Fontes e atualizações
Fontes primárias:
- PHP: aviso de segurança de 21 de outubro de 2026, aviso informativo de 23 de outubro de 2026, GHSA-w8hw-w9fx-j79w, GHSA-6wmf-4rv5-p3rp, versões suportadas
- Registos CVE: CVE-2026-109618, CVE-2026-109619
- CISA: alerta de 21 de outubro de 2026, catálogo KEV
- NCSC-NL: repositório php2shell
- NVD: CVE-2026-109618, CVE-2026-109619
- FIRST: pontuações EPSS
Investigação e análise:
- Calif: PHP2Shell, a tale of two PHP remote vulnerabilities
- Amazon Threat Intelligence
- watchTowr
- Akamai
- CybelAngel
- php2shell-scanner da Searchlight Cyber
Atualizações:
- 2026-11-11: Acrescentados à caixa as pontuações do NVD, o EPSS, as classes CWE, os créditos, as versões seguras mais recentes e as datas de fim de vida, o PHP 8.6.0 RC4 e secções sobre como funcionam os erros, a verificação da correção e a verificação de comprometimento.
- 2026-11-11: Primeira publicação.