Em 21 de outubro de 2026 o PHP corrigiu duas falhas críticas (CVSS 9,2) que permitem executar código sem autenticação; a única mitigação completa é atualizar para a 8.5.12, 8.4.27, 8.3.36 ou 8.2.35, e quem usa a 8.1 ou anterior deve pedir um patch ao provedor ou migrar.
1. O que aconteceu#
Em 20 de outubro de 2026 o projeto PHP avisou de um lançamento de segurança urgente para o dia seguinte. Em 21 de outubro publicou as versões 8.5.12, 8.4.27, 8.3.36 e 8.2.35, que corrigem duas vulnerabilidades críticas que permitem execução remota de código sem autenticação. A imprensa as chama de PHP2Shell.
| Data (2026) | Fato |
|---|---|
| 20 de outubro | O PHP anuncia um lançamento de segurança para 21 de outubro às 14:00 UTC, com duas falhas críticas (CVSS 9,2), e se reserva o direito de antecipar se os detalhes se tornarem públicos |
| Antes dos patches | O CTO da Cloudflare disse que já via ataques iniciais contra ambas as falhas; as regras de WAF eram temporárias |
| 21 de outubro | Saem o PHP 8.5.12, 8.4.27, 8.3.36 e 8.2.35, com os avisos publicados no repositório do PHP |
| 21 a 22 de outubro | A Qualys informa que em 12 horas só 199.000 de 155 milhões de instalações com versão conhecida estavam corrigidas |
Há sinais de exploração: a Cloudflare disse que já via ataques iniciais contra ambas as falhas antes dos patches, e o PHP descreve um exploit demonstrado no Apache com mod_php. O Centro Nacional de Cibersegurança do Reino Unido pediu atualização imediata ou desligar os sistemas afetados.
As fontes divergem em um detalhe: os avisos e a página de notícias do PHP datam os lançamentos de 21 de outubro, enquanto o registro de mudanças do php.net mostra o dia 22 para a 8.5.12 e a 8.4.27. Usamos o dia 21, a data dos avisos.
Documentação: PHP: arquivo de notícias de 2026 (inglês) ↗
2. As duas vulnerabilidades#
Ambas têm CVSS v4.0 de 9,2 (crítica). Segundo o BleepingComputer, foram descobertas pela Calif, OpenAI e Wiz. Baseiam-se no mesmo problema de fundo: o PHP deixa memória corrompida quando uma requisição termina de forma anormal.
| Dado | CVE-2026-109618 | CVE-2026-109619 |
|---|---|---|
| Aviso | GHSA-w8hw-w9fx-j79w | GHSA-6wmf-4rv5-p3rp |
| Nome do aviso | RCE por corrupção de memória ao ficar sem memória (OOM) | RCE por estado global obsoleto |
| CVSS v4.0 | 9,2 crítica (AV:N/AC:H/AT:P/PR:N/UI:N) | 9,2 crítica (AV:N/AC:H/AT:P/PR:N/UI:N) |
| Mecanismo | O PHP sai de um erro de memória com longjmp() e deixa dados da requisição semi-inicializados que o encerramento trata como válidos | O estado global de uma requisição sobrevive à sua memória liberada e uma requisição posterior do mesmo worker o usa antes de reiniciá-lo |
| Impacto confirmado | Execução remota de código sem autenticação com os privilégios do worker web | Use-after-free, vazamento de memória e execução remota de código sem autenticação |
| Onde foi confirmado | Apache mod_php com limites padrão | mod_php (backtraces fatais do PHP 8.5) e mod_php e PHP-FPM (progresso de upload de sessão) |
A primeira falha dispara quando a memória acaba. Os avisos descrevem várias formas de levar uma requisição a esse estado sem sair dos limites aparentes: requisições multipart sem um comprimento declarado utilizável, número ilimitado de cabeçalhos por parte e campos de arquivo vazios com nomes aninhados. A segunda precisa de duas requisições atendidas pelo mesmo worker: uma que deixa o estado obsoleto e outra que o usa.
O aviso esclarece que o sucesso do exploit depende da compilação do PHP, das extensões e da disposição da memória, então é mais difícil em alguns ambientes do que em outros. Isso não o torna seguro: os pesquisadores demonstraram execução de código com limites padrão.
Documentação: Aviso GHSA-w8hw-w9fx-j79w (CVE-2026-109618, inglês) ↗ · Aviso GHSA-6wmf-4rv5-p3rp (CVE-2026-109619, inglês) ↗
3. Quem é afetado#
Afetam todas as versões abaixo de 8.2.35, 8.3.36, 8.4.27 e 8.5.12. A Qualys e a imprensa incluem no risco qualquer instalação que atenda requisições web: PHP-FPM, Apache com mod_php, php-cgi, FrankenPHP e LiteSpeed.
| Ramo do PHP | Versão corrigida | Estado |
|---|---|---|
| 8.5 | 8.5.12 | Com suporte |
| 8.4 | 8.4.27 | Com suporte |
| 8.3 | 8.3.36 | Com suporte |
| 8.2 | 8.2.35 | Termina a vida útil em 31 de dezembro de 2026 |
| 8.1, 8.0 e 7.4 | Sem versão corrigida oficial | Fora de suporte; o PHP oferece patches de código-fonte para 7.4, 8.0 e 8.1 |
O caso mais urgente é o Apache com mod_php: o aviso descreve um exploit que dispara antes de o código da aplicação rodar. No PHP-FPM a primeira falha não está demonstrada por completo, mas o PHP validou execução de código pela via da sessão. A linha de comando não é mencionada.
Os ramos 8.1, 8.0 e 7.4 não recebem atualizações do projeto; o PHP oferece patches de código-fonte que o seu provedor deve aplicar. A Qualys estima que, das 167 milhões de instalações de PHP que analisou, 71 % usam versões sem suporte (de 5.4 a 8.1). É um número de um fornecedor de segurança: use-o como ordem de grandeza.
Documentação: Qualys: PHP2Shell, como encontrar, mitigar e corrigir (inglês) ↗ · BleepingComputer: patches de emergência para o PHP2Shell (inglês) ↗
4. Como saber se você está afetado#
Veja a versão que atende as requisições web, não a que aparece no seu terminal: a Qualys alerta que php -v pode mostrar uma instalação diferente da que atende o site. Revise também os contêineres, os ramos paralelos e o PHP que vem nos painéis de hospedagem.
# A versão que atende as requisições web (não a do terminal): compare com a do processo em execução
php -v
php-fpm -v || php-fpm8.4 -v
apache2ctl -M 2>/dev/null | grep -i php # mod_php carregado?
ps aux | grep -E "php-fpm|apache2|httpd|frankenphp" | grep -v grep
# Contêineres: a imagem que roda, não a do seu notebook
docker ps --format "{{.Names}} {{.Image}}"
docker exec NOME php -v
# Depois de atualizar: reinicie de verdade os processos que atendem requisições
sudo systemctl restart php8.4-fpm # ou apache2 se usa mod_phpO script compara uma versão com as corrigidas. Se você usa um pacote de uma distribuição, o número pode continuar antigo mesmo com o patch: consulte o aviso do seu provedor.
import re
CORRIGIDAS = {(8, 5): 12, (8, 4): 27, (8, 3): 36, (8, 2): 35} # nível de patch corrigido por ramo
def parsear(version):
return tuple(int(n) for n in re.findall(r"\d+", version)[:3])
def estado(version):
maior, menor, patch = parsear(version)
if (maior, menor) in CORRIGIDAS:
minimo = CORRIGIDAS[(maior, menor)]
if patch >= minimo:
return "corrigida"
return f"VULNERAVEL: atualize para {maior}.{menor}.{minimo}"
if (maior, menor) > (8, 5):
return "ramo mais novo que os corrigidos: revise os avisos"
return "SEM VERSAO CORRIGIDA OFICIAL: peça ao seu provedor um build com o patch ou migre"
for v in ["8.5.11", "8.5.12", "8.4.26", "8.4.27", "8.3.36", "8.2.34", "8.1.31", "7.4.33"]:
print(v, "->", estado(v))5. Como corrigir#
- Atualize para a 8.5.12, 8.4.27, 8.3.36 ou 8.2.35 conforme o seu ramo. Se está na 8.1 ou anterior, peça ao provedor um build com o patch ou migre para um ramo com suporte.
- Reinicie os processos que atendem requisições (PHP-FPM, Apache, FrankenPHP): atualizar o pacote não basta até que os workers carreguem a nova versão.
- Em contêineres, reconstrua a imagem sobre uma base com a versão corrigida e implante de novo.
- Em hospedagem compartilhada ou com painel (Plesk, cPanel), confirme com o provedor que ele aplicou o patch.
- Se o PHP 8.2 é o seu ramo, planeje a migração: ele chega ao fim da vida útil em 31 de dezembro de 2026.
Para se aprofundarPatches de segurança de outubro de 2026: Next.js 16.4.1 e PgBouncer 1.26.1
6. Se você não pode corrigir hoje: mitigações temporárias#
O PHP publica ajustes que reduzem a exposição, mas insiste que não tornam seguro um sistema sem correção: a única mitigação completa é atualizar. Devem ser aplicados de forma administrativa (php.ini, o pool do FPM ou a configuração do servidor), não com ini_set() nem .user.ini, e é preciso reiniciar os workers.
| Ajuste | Valor | Protege de |
|---|---|---|
| memory_limit | -1, definido com php_admin_value | CVE-2026-109618 |
| post_max_size | 8M sem uploads; 32M com uploads | CVE-2026-109618 |
| upload_max_filesize | Menor que post_max_size | CVE-2026-109618 |
| session.upload_progress.enabled | 0 no php.ini, no pool do FPM ou no servidor; não com ini_set() nem .user.ini | CVE-2026-109619 |
| fatal_error_backtraces | 0, somente no PHP 8.5 | CVE-2026-109619 (a via confirmada do PHP 8.5) |
| pm.max_requests | 1, somente no FPM e com custo de desempenho | CVE-2026-109619 |
import re
def a_mb(valor):
m = re.fullmatch(r"(\d+)\s*([KMG]?)", valor.strip().upper())
if not m:
return None
return int(m.group(1)) * {"": 1 / 1024**2, "K": 1 / 1024, "M": 1, "G": 1024}[m.group(2)]
def auditar(ini, version):
"""Revisa as mitigações temporárias que o PHP lista; não substituem o patch."""
cfg = dict(l.split("=", 1) for l in (x.split(";")[0].strip() for x in ini.splitlines()) if "=" in l)
cfg = {k.strip(): v.strip() for k, v in cfg.items()}
faltam = []
if cfg.get("memory_limit") != "-1":
faltam.append("memory_limit = -1 (definido como php_admin_value)")
limite = a_mb(cfg.get("post_max_size", "8M"))
if limite is None or limite > 32:
faltam.append("post_max_size <= 32M (8M se não há uploads)")
if cfg.get("session.upload_progress.enabled", "1").lower() not in ("0", "off"):
faltam.append("session.upload_progress.enabled = 0")
if parsear(version)[:2] == (8, 5) and cfg.get("fatal_error_backtraces", "1").lower() not in ("0", "off"):
faltam.append("fatal_error_backtraces = 0 (somente PHP 8.5)")
return faltam
def parsear(version):
return tuple(int(n) for n in re.findall(r"\d+", version)[:3])
parcial = "memory_limit = -1\npost_max_size = 8M ; sem uploads\nsession.upload_progress.enabled = 0\n"
print(auditar(parcial, "8.4.26"))
print(auditar(parcial, "8.5.11"))
print(auditar("memory_limit = 128M\npost_max_size = 64M\n", "8.3.35"))Dois avisos do aviso: não use limites de processo RLIMIT_AS nem RLIMIT_DATA, porque podem ativar justamente o caminho vulnerável, e ocultar erros com error_reporting, display_errors ou o operador @ não ajuda. Além disso, memory_limit = -1 só funciona se nenhuma aplicação puder definir um limite finito de novo.
7. Depois de corrigir#
A Qualys informa que os pesquisadores demonstraram o vazamento de memória dos workers sem autenticação, o que pode expor senhas, tokens e chaves de API. Se o seu servidor esteve exposto com uma versão vulnerável, trate os segredos que passaram pelo PHP como possivelmente comprometidos.
- Troque as credenciais de banco de dados, as chaves de API e os tokens de sessão que aquela aplicação manipulava.
- Revise os logs do servidor e do PHP desde 20 de outubro: requisições multipart estranhas ou muito grandes, erros fatais repetidos e reinícios de workers.
- Procure arquivos novos ou modificados no diretório web e nas pastas de upload.
- Mantenha uma regra de WAF que limite ou bloqueie multipart onde você não o usa, como medida adicional, não como substituta do patch.
- Anote a data e a versão em que corrigiu cada servidor.
Estas recomendações são de boa prática, não do aviso do PHP; adapte-as ao seu ambiente e à sua equipe de segurança.
8. Mantenha seus números em dia#
As versões, os identificadores e as mitigações são os dos avisos publicados até 22 de outubro de 2026. Podem surgir novos avisos e detalhes de exploração; revise o repositório de segurança do PHP e o aviso da sua distribuição.
- Assine os avisos de segurança do PHP e do seu provedor.
- Mantenha um inventário de qual versão do PHP roda em cada servidor e contêiner.
- Automatize um alerta quando uma versão ficar abaixo da corrigida.
Fontes e escopo
Documentação consultada em 22 de outubro de 2026. Os exemplos e critérios de decisão são propostas editoriais; adapte-os ao contrato da sua aplicação e valide-os no seu ambiente de testes autorizado.