PHP2Shell: Falha de Segurança Crítica no PHP. Como Resolver no GW Server, WordOps e CloudPanel

O WordPress funciona em cima do PHP, a linguagem de programação que monta as páginas do seu site. Em 21 de outubro, os responsáveis pelo PHP avisaram que encontraram duas falhas graves nele. O apelido que pegou foi PHP2Shell.

Grave quanto? Com essas falhas, alguém de fora consegue rodar comandos no seu servidor sem precisar de senha nenhuma. Na prática, é como deixar a chave do servidor na porta. E já há relatos de gente explorando isso.

Dois dias depois veio um segundo aviso: uma terceira falha, parecida, que ainda não tem conserto.

Se o seu site roda num servidor próprio (VPS) com WordOps, CloudPanel ou GW Server, isso é com você. Nesta semana eu corrigi os meus servidores e os de alguns clientes. Abaixo está exatamente o que eu fiz, passo a passo, com as telas reais. Nas telas, troquei o nome dos servidores e dos sites dos clientes.

Resumo para quem tem pressa

  • Primeiro, uma proteção provisória: desligar uma opção do PHP que o WordPress não usa. Leva 5 minutos e não quebra o site.
  • Depois, o conserto: atualizar o PHP para a versão corrigida.
  • A proteção provisória fica, mesmo depois de atualizar, porque a terceira falha ainda não tem conserto.
  • GW Server: o botão de atualizar do painel faz tudo isso sozinho.
  • WordOps e CloudPanel: é na mão, com os comandos abaixo.

Pequeno dicionário antes de começar

  • Terminal (SSH): a tela preta onde você digita comandos no servidor. Você entra como root, o usuário que pode tudo.
  • PHP-FPM: a parte do PHP que atende os visitantes do site. Cada versão do PHP (7.4, 8.2, 8.3…) tem o seu.
  • Nginx: o programa que recebe os visitantes e entrega o site. Ele passa o trabalho para o PHP.
  • Snapshot: uma cópia do servidor inteiro, feita no painel do seu provedor (DigitalOcean, Vultr, Hetzner…). Se algo der errado, você volta tudo em poucos cliques.
  • CVE: o código que identifica cada falha, como um número de protocolo.

1. O problema, em linguagem simples

Pense no seu servidor como uma casa. As falhas são uma fechadura com defeito: quem sabe o truque abre a porta.

  • A proteção provisória é colocar um cadeado extra enquanto a fechadura não é trocada. No PHP, isso é desligar uma opção chamada session.upload_progress, que mostra o andamento de envio de arquivos. O WordPress não usa essa opção: o envio de imagens dele mostra o progresso pelo próprio navegador.
  • O conserto é trocar a fechadura: atualizar o PHP. As versões consertadas são a 8.5.12, 8.4.27, 8.3.36 e 8.2.35 (ou mais novas).

Dois avisos importantes:

  • PHP 7.4, 8.0 e 8.1 não vão ganhar conserto. Essas versões são antigas e os responsáveis pelo PHP não cuidam mais delas. Se algum site seu usa uma delas, o cadeado ajuda, mas a solução de verdade é passar o site para o PHP 8.3 ou 8.4.
  • A terceira falha ainda não tem conserto em nenhuma versão. Por isso o cadeado fica até sair a próxima versão do PHP. Ela só funciona numa configuração rara, que nenhum dos sites que eu conferi usa, mas a recomendação oficial é proteger mesmo assim.
Para os técnicos: os detalhes das três falhas
  • CVE-2026-109618 (PHP2Shell): quando falta memória no meio de uma requisição, dados pela metade são tratados como válidos na limpeza. Só fecha atualizando; o cadeado não cobre esta.
  • CVE-2026-109619 (PHP2Shell): um dado interno sobrevive entre requisições no mesmo processo do PHP-FPM. O cadeado (session.upload_progress.enabled = 0) bloqueia o caminho dela.
  • CVE-2026-115560 (aviso de 23/10): só com session.serialize_handler em php_binary ou php_serialize trocado para php com ini_set() antes do session_start(). Sem conserto ainda; a proteção é o mesmo cadeado.
  • No PHP 8.5, o php.net pede também fatal_error_backtraces = 0. A configuração vale no php.ini, no conf.d ou no pool; não vale por .user.ini nem ini_set(). O php.net cita ainda memory_limit = -1 e post_max_size = 8M para a 109618, mas eu não recomendo: o primeiro deixa um script descontrolado tomar a memória do servidor, e o segundo quebra o envio de mídia maior.

2. GW Server: um clique

No GW Server, eu coloquei tudo isso dentro do botão de atualizar o painel. Quando você atualiza, o painel:

  • confere cada versão do PHP do servidor e atualiza para a versão consertada;
  • se o conserto ainda não saiu para o seu servidor, coloca o cadeado sozinho e termina o serviço na próxima atualização;
  • atualiza também o Nginx, que teve as próprias falhas (parte 5).

Um detalhe: o conserto do PHP para servidores ARM, como os da Oracle Cloud gratuita, atrasou no repositório oficial. Para esses servidores não ficarem esperando, o painel busca os pacotes consertados direto do mesmo mantenedor, conferindo a assinatura.

A partir da versão 2.35.41, o painel também mantém o cadeado da terceira falha em todas as versões do PHP, até sair o conserto. Quando sair, a atualização seguinte troca a fechadura e tira o cadeado.

Como atualizar

  1. Faça um snapshot do servidor no seu provedor.
  2. No painel, abra Configurações → Atualizações e clique em Verificar atualizações.
  3. Marque a caixa confirmando que fez o snapshot e clique em Atualizar.

Prefere pelo terminal? Eu prefiro, porque dá para acompanhar cada passo. Entre no servidor como root e cole:

bash <(curl -sL https://cdn.g-web.link/gw-server/panel/panel-install.sh) --update

No fim, procure a linha PHP em dia com as correcoes de seguranca. Nos meus servidores, todos com GW Server, isso entrou em 21 e 22 de outubro.

3. WordOps: passo a passo

No WordOps, nada disso se atualiza sozinho. Fiz o passo a passo abaixo num servidor de cliente com WordOps, Ubuntu 24.04 e PHP 7.4, 8.2 e 8.3. É só copiar e colar cada bloco no terminal, um de cada vez.

Antes de começar: faça o snapshot e escolha um horário com pouca visita. No passo 5 o PHP reinicia, e um visitante que estiver carregando a página exatamente naquele segundo pode ver um erro. Recarregando, volta ao normal.

Passo 1: veja quais versões do PHP o servidor tem

ls /etc/php/
systemctl list-units 'php*-fpm.service' --no-pager
Terminal do servidor WordOps: Neste servidor, três versões do PHP estão rodando
Neste servidor, três versões do PHP estão rodando.

O que você deve ver: a lista de versões e cada uma como running (rodando). Todas vão receber o cadeado, mesmo as que nenhum site usa.

Passo 2: confira se a opção perigosa está ligada

for v in $(ls /etc/php); do
  echo "PHP $(php-fpm$v -v | head -1 | cut -d" " -f2): $(php-fpm$v -i | grep '^session.upload_progress.enabled')"
done
Terminal do servidor WordOps: On em todas: a opção vem ligada de fábrica no PHP
On em todas: a opção vem ligada de fábrica no PHP.

O que você deve ver: On em todas as linhas. É normal: o PHP vem assim.

Passo 3: veja se algum site religa a opção

Às vezes uma configuração de site liga essa opção de novo. Este comando procura:

grep -rln 'upload_progress' /etc/php/*/fpm/pool.d/ /var/www/*/htdocs \
  --include='*.conf' --include='.user.ini' --include='.htaccess' \
  || echo 'Nenhuma configuração religa o upload_progress'
Terminal do servidor WordOps: Nenhuma configuração de site liga a opção de novo
Nenhuma configuração de site liga a opção de novo.

O que você deve ver: a frase “Nenhuma configuração religa o upload_progress”. Se aparecer o nome de algum arquivo, abra e apague a linha do upload_progress dele.

Passo 4: coloque o cadeado

Este comando cria um pequeno arquivo de configuração em cada versão do PHP, desligando a opção:

for d in /etc/php/*/fpm/conf.d; do
  printf '%s\n' '; Mitigacao CVE-2026-109619 (PHP2Shell) e CVE-2026-115560 - php.net, out/2026' \
    'session.upload_progress.enabled = 0' > "$d/99-mitigacao-php.ini"
done
cat /etc/php/8.3/fpm/conf.d/99-mitigacao-php.ini
Terminal do servidor WordOps: O arquivo criado: uma linha de comentário e a opção desligada
O arquivo criado: uma linha de comentário e a opção desligada.

O que você deve ver: as duas linhas do arquivo, terminando em session.upload_progress.enabled = 0. Se o seu servidor tiver PHP 8.5, rode também:

echo 'fatal_error_backtraces = 0' >> /etc/php/8.5/fpm/conf.d/99-mitigacao-php.ini

Passo 5: teste e reinicie o PHP

Primeiro, teste se a configuração está certa:

for v in $(ls /etc/php); do php-fpm$v -t; done
Terminal do servidor WordOps: "test is successful" em todas: pode reiniciar
“test is successful” em todas: pode reiniciar.

O que você deve ver: test is successful em todas. Se alguma der erro, pare aqui e apague o arquivo daquela versão. Com tudo certo, reinicie o PHP, uma versão de cada vez:

for v in $(ls /etc/php); do
  systemctl restart php$v-fpm && echo "php$v-fpm reiniciado"
  sleep 2
done
systemctl list-units 'php*-fpm.service' --no-pager
Terminal do servidor WordOps: Cada versão reiniciada e de volta como running
Cada versão reiniciada e de volta como running.

Enquanto isso, deixei um programa visitando todos os sites do cliente a cada segundo: nenhum erro em 208 visitas.

Passo 6: confira

Repita o comando do passo 2:

for v in $(ls /etc/php); do
  echo "PHP $(php-fpm$v -v | head -1 | cut -d" " -f2): $(php-fpm$v -i | grep '^session.upload_progress.enabled')"
done
Terminal do servidor WordOps: Off em todas: o cadeado está no lugar
Off em todas: o cadeado está no lugar.

O que você deve ver: Off em todas. Agora confira se os sites abrem (troque pelos seus endereços):

for site in seusite.com.br www.seusite.com.br; do
  echo "$site -> $(curl -s -o /dev/null -w '%{http_code}' https://$site/)"
done
Terminal do servidor WordOps: Sites respondendo normalmente
Sites respondendo normalmente.

Os números 200 e 301 significam que está tudo certo.

Passo 7: troque a fechadura (atualize o PHP)

Com o cadeado no lugar, veja se o conserto já chegou:

apt-get update -qq 2>/dev/null
apt list --upgradable 2>/dev/null | grep -E '^php[0-9.]+-fpm/'
Terminal do servidor WordOps: Em 23/10, já havia o 8.2.35 e o 8.3.36 para instalar
Em 23/10, já havia o 8.2.35 e o 8.3.36 para instalar.

Se aparecer a versão nova, atualize pelo próprio WordOps. Ele mostra o que vai instalar e pede confirmação:

wo stack upgrade --php
php-fpm8.3 -v | head -1

Não apague o arquivo do cadeado depois de atualizar. Ele continua protegendo da terceira falha, que ainda não tem conserto.

Se um site seu usa PHP 7.4, o cadeado ajuda, mas a fechadura dessa versão não vai ser trocada nunca. O caminho é passar o site para o 8.3 ou o 8.4.

4. CloudPanel: os mesmos passos, com um extra

O CloudPanel instala de uma vez todas as versões do PHP, da 7.1 à 8.5, e deixa todas rodando. Fiz em dois servidores de clientes.

Terminal do servidor CloudPanel: No CloudPanel, dez versões do PHP rodando ao mesmo tempo
No CloudPanel, dez versões do PHP rodando ao mesmo tempo.

Os comandos são os mesmos do WordOps, com duas diferenças:

  • no passo 3, troque /var/www/*/htdocs por /home/*/htdocs, que é onde o CloudPanel guarda os sites;
  • como o CloudPanel tem o PHP 8.5, o comando extra do passo 4 entra sempre.
Terminal do servidor CloudPanel: Antes: On nas dez versões
Antes: On nas dez versões.
Terminal do servidor CloudPanel: O cadeado, com a linha extra do PHP 8.5
O cadeado, com a linha extra do PHP 8.5.
Terminal do servidor CloudPanel: Depois de testar e reiniciar: Off nas dez versões
Depois de testar e reiniciar: Off nas dez versões.

O extra: o PHP do próprio painel. A tela do CloudPanel, aquela em que você faz login, roda num PHP separado, na versão 8.1, que não vai ganhar conserto. Ela pega o cadeado do passo 4, mas só depois de reiniciada. Nos dois servidores dos clientes, esse PHP rodava havia meses, sem o cadeado, e a tela de login estava aberta na internet.

Reinicie o PHP do painel com o comando abaixo. Isso não afeta os sites, só a tela do CloudPanel:

systemctl restart clp-php-fpm

Enquanto o CloudPanel não trocar o PHP 8.1 do painel, vale também restringir o acesso à tela de login aos IPs de quem administra o servidor.

Nos dois servidores, o programa que visitava os sites a cada segundo registrou um único erro em 286 visitas: um visitante pegou um erro 502 no exato segundo em que o PHP do site dele reiniciava. Na visita seguinte, o site abriu normalmente. É o motivo do horário com pouca visita.

Atualizando o PHP no CloudPanel

Os dois servidores estavam sem atualizar desde março. Depois de buscar as atualizações, o CloudPanel já tinha o PHP consertado:

Terminal do servidor CloudPanel: O CloudPanel já oferece 8.2.35, 8.3.36, 8.4.27 e 8.5.12
O CloudPanel já oferece 8.2.35, 8.3.36, 8.4.27 e 8.5.12.
apt update
apt upgrade

O apt upgrade mostra a lista de tudo o que vai atualizar e pede confirmação. Se o servidor ficou muito tempo parado, a lista é grande: leia antes de confirmar e faça com o snapshot pronto. As versões 7.1 a 8.1 não têm conserto; mantenha o cadeado e passe os sites para o 8.3 ou 8.4. E aqui também o arquivo do cadeado fica.

5. As outras falhas: o Nginx

O PHP não foi o único. O Nginx, que recebe os visitantes antes do PHP, também corrigiu uma série de falhas nos últimos meses. A versão segura hoje é a 1.30.6, de 14 de outubro.

Aqui tem uma diferença importante: você depende de quem mantém o seu painel. O Nginx do WordOps e o do CloudPanel são montados pelos próprios projetos, com peças próprias. Não dá para trocar pelo Nginx oficial sem quebrar o painel. Então a correção só chega quando eles publicam.

O que eu encontrei nos servidores dos clientes, em 23 de outubro:

  • GW Server: o Nginx é montado por nós. Quando a 1.30.6 saiu, refiz o pacote, testei e coloquei nos meus servidores em 18/10. Os clientes recebem pelo botão de atualizar.
  • CloudPanel: os servidores estavam na 1.28.0, e o CloudPanel já oferece a 1.30.6. O apt upgrade da parte 4 resolve.
  • WordOps: o servidor estava na 1.28.0, e o WordOps oferece a 1.30.5. Ela resolve a maior parte, mas ficam 5 falhas que só a 1.30.6 corrige. Até o WordOps publicar, não há o que fazer.

A versão 1.28.0, que estava nos três servidores, tem 23 falhas conhecidas publicadas entre 2025 e 2026. Para ver a sua versão e se há atualização:

nginx -v
apt list --upgradable 2>/dev/null | grep -i nginx

No WordOps, atualize o Nginx pelo próprio painel:

wo stack upgrade --nginx
Para os técnicos: o que cada versão do Nginx corrigiu desde a 1.30.3
  • 1.30.4: CVE-2026-42533 (grave: estouro de memória com map e expressão regular), CVE-2026-60005 (módulo slice) e CVE-2026-56434 (SSI).
  • 1.30.5: CVE-2026-90439 (HTTP/3).
  • 1.30.6: CVE-2026-93479 (estouro de memória na avaliação de expressões), CVE-2026-15176 (alias com rewrite), CVE-2026-95101 (HTTP/3), CVE-2026-97629 (sessões TLS com tickets) e CVE-2026-97205 (leitura assíncrona de arquivos).

Várias dependem de um módulo ou recurso específico, então nem toda falha atinge toda configuração. O GW Server usa um Nginx compilado com GeoIP2 (bloqueio por país), limpeza de cache e Brotli.

Checklist

  • Snapshot feito antes de mexer.
  • Cadeado no lugar: Off em todas as versões do PHP (passo 6).
  • No CloudPanel, o PHP do painel reiniciado (clp-php-fpm).
  • PHP atualizado para 8.5.12, 8.4.27, 8.3.36 ou 8.2.35 (ou mais novo).
  • Sites em PHP 7.x, 8.0 ou 8.1 com mudança para o 8.3 ou 8.4 planejada.
  • Nginx na versão mais nova que o seu painel oferece.
  • Arquivo do cadeado mantido até sair o conserto da terceira falha.

GW Server

Quer que isso aconteça sozinho no seu servidor?

Tudo o que fiz na mão no WordOps e no CloudPanel, o GW Server faz no botão de atualizar: PHP consertado em cada versão (inclusive em ARM), cadeado colocado quando o conserto ainda não saiu e Nginx montado e atualizado por nós. O servidor continua seu, com WordPress, Mautic, n8n e as outras aplicações no mesmo VPS.

Quero conhecer o GW Server →

Dá para começar no plano gratuito, com até 2 instalações.

Perguntas frequentes

Desligar essa opção quebra o meu site?

Não. O WordPress não usa essa opção: o envio de imagens mostra o progresso pelo navegador. Nos três servidores de clientes, todos os sites continuaram abrindo normalmente.

Já atualizei o PHP. Posso tirar o cadeado?

Ainda não. A atualização conserta as duas primeiras falhas, mas a terceira continua aberta em todas as versões. Tire só quando sair o conserto dela e você atualizar de novo.

Meu site usa PHP 7.4, 8.0 ou 8.1. E agora?

Coloque o cadeado agora e planeje passar o site para o 8.3 ou o 8.4. Essas versões não recebem mais conserto, e uma das falhas continua aberta nelas mesmo com o cadeado.

As versões do PHP que nenhum site usa também são perigosas?

Bem menos. Para explorar a falha, alguém precisa mandar uma visita que chegue naquela versão, e o Nginx só manda visitas para as versões que os sites usam. Mesmo assim, coloque o cadeado em todas: é o mesmo comando e não custa nada.

Preciso reiniciar o servidor?

Não. Basta reiniciar o PHP de cada versão, como no passo 5. O resto do servidor continua como está.

Fontes: avisos de segurança do php.net (21 e 23/10/2026) e avisos de segurança do Nginx.

Autor

Gabriel Wohlfart é CEO do Gerenciando Web e especialista em WordPress, Servidores Cloud, Mautic, SEO e Automação.
Mais de 3.500 alunos já passaram pelos seus cursos. Saiba mais.