mod_php ou PHP-FPM: Risco, Desempenho e Migração
O PHP apontou o mod_php como o pior cenário no PHP2Shell. Veja o que muda na arquitetura e como migrar para FPM sem parar o site.
por Cleverson Gouvêa

Escolher entre mod_php ou PHP-FPM deixou de ser uma decisão de desempenho e virou uma decisão de risco. No aviso de 21 de outubro de 2026 sobre o PHP2Shell, a própria equipe de segurança do PHP escreveu que o risco é maior no mod_php, porque o ataque demonstrado dispara antes de qualquer linha do código da aplicação. Neste comparativo eu mostro a diferença de arquitetura, segurança e desempenho, e como migrar sem tirar o site do ar.
TL;DR
- O PHP2Shell (CVE-2026-109618 e CVE-2026-109619) é execução remota de código sem autenticação, com CVSS 4.0 de 9,2. A correção saiu em 21/10/2026 nas versões 8.5.12, 8.4.27, 8.3.36 e 8.2.35.
- Todos os modos de rodar PHP para web estão afetados: PHP-FPM, Apache com mod_php, php-cgi, FrankenPHP e LiteSpeed. Mas o PHP classifica o mod_php como o cenário de maior risco.
- Migrar para PHP-FPM não substitui o patch. A ordem certa é atualizar o PHP primeiro e migrar depois, com calma.
- O próprio manual do PHP já diz para não usar mod_php em instalações novas: ele prende o Apache no MPM prefork, que limita a concorrência.
- A migração em Apache leva poucos comandos, mas tem armadilhas reais:
php_valueno.htaccesspara de funcionar e o pool do FPM precisa ser dimensionado.
O que muda na escolha mod_php ou PHP-FPM depois do PHP2Shell
Até a semana passada, a conversa sobre mod_php ou PHP-FPM era sobre memória, concorrência e comodidade. O mod_php era o caminho "funciona de primeira" do Apache, e muito servidor antigo ficou nele por inércia.
O PHP2Shell mudou o peso dessa escolha. Os fatos, confirmados nas fontes oficiais:
- Duas falhas, ambas sem autenticação. A CVE-2026-109618 é uma corrupção de memória no tratamento de out-of-memory (falta de memória): o PHP é interrompido com dados internos da requisição montados pela metade, e a limpeza do fim da requisição trata esses dados como válidos. A CVE-2026-109619 é estado global obsoleto (use-after-free): um dado interno sobrevive à memória que ele apontava, e a requisição seguinte no mesmo processo usa esse lixo.
- Gravidade. As duas têm CVSS 4.0 de 9,2, segundo a equipe de segurança do PHP. O FAQ da Tenable registra que identificadores com nota 10,0 circularam antes e estavam errados.
- Linha do tempo. A Amazon viu uma tentativa de exploração no seu honeypot em 17/10, quatro dias antes da divulgação, segundo a Tenable. Os detalhes vazaram em 20/10, antes da data coordenada, e o PHP antecipou a correção para 21/10 às 14h UTC, segundo a Huntress.
- Exposição. A Unit 42, da Palo Alto Networks, contou pelo Cortex Xpanse mais de 22,6 milhões de instâncias expostas potencialmente vulneráveis.
E a frase que muda a conta de mod_php ou PHP-FPM para quem decide infraestrutura vem do aviso oficial do PHP: o risco é considerado maior para o mod_php, "com um exploit demonstrado em que uma requisição não autenticada pode disparar o ataque antes de qualquer código da aplicação rodar".
Traduzindo para quem paga a conta: no mod_php, não importa se o seu WordPress, Moodle ou Laravel está atualizado e bem escrito. O ataque acontece antes de a aplicação ter chance de fazer qualquer coisa.
Arquitetura: como cada modelo roda o PHP
Para entender por que o risco muda entre mod_php ou PHP-FPM na prática, vale olhar onde o PHP vive em cada modelo.
mod_php: o PHP dentro do Apache
No mod_php (o módulo apache2handler), o interpretador PHP é carregado dentro de cada processo do Apache. Cada processo filho do servidor web é, ao mesmo tempo, servidor HTTP e interpretador PHP.
Isso tem duas consequências diretas:
- O Apache fica preso ao MPM prefork. O manual do PHP diz que, sem PHP compilado com thread safety (ZTS), o mod_php exige o prefork, "o que limita significativamente a concorrência". A maioria dos pacotes de distribuição não vem com ZTS.
- Todo processo carrega o PHP, mesmo para servir uma imagem. Um pedido de
logo.pngocupa um processo inteiro com o interpretador carregado.
PHP-FPM: o PHP como serviço separado
No PHP-FPM (FastCGI Process Manager), o PHP roda num serviço próprio, com pools de processos. O servidor web (Apache com mod_proxy_fcgi ou Nginx) só repassa as requisições .php para o pool, por socket Unix ou TCP.
Cada pool tem seu usuário, seu limite de processos e suas configurações. A documentação de configuração do FPM traz as diretivas que fazem a diferença na prática: user/group, pm.max_children, pm.max_requests, request_terminate_timeout e php_admin_value, esta última com valores que o script não consegue sobrescrever com ini_set().
E quem usa Nginx?
Nginx não tem módulo de PHP embutido. Se o seu site roda em Nginx, você já está em PHP-FPM (ou em outro processo FastCGI) e a pergunta mod_php ou PHP-FPM não se aplica. Isso não te tira do PHP2Shell: o FPM também está na lista de afetados.
Segurança: por que o mod_php é o pior cenário
O ponto central na comparação mod_php ou PHP-FPM não é que o FPM seja imune. Não é. O ponto é que o mod_php junta três fatores ruins no mesmo processo.
O ataque roda antes da aplicação
O relato técnico da Datadog Security Labs detalha o que o PHP confirmou. No caminho de upload da CVE-2026-109619, houve execução de comandos tanto em mod_php quanto em PHP-FPM, mas no FPM o ataque também exige que a aplicação faça uma operação adequada depois que a inicialização terminou. No mod_php, não há essa condição.
Para a CVE-2026-109618, a Huntress registra que o PHP validou RCE completo via HTTP contra mod_php com os limites padrão de entrada e memória e configurações prefork normais. O laboratório da Datadog também usou Apache prefork com mod_php.
Um usuário para todos os sites
No mod_php, todo site do servidor roda como o usuário do Apache (www-data no Debian/Ubuntu, apache no Red Hat). Se um atacante executa comando por um site, ele tem a permissão do Apache, que normalmente lê os arquivos de todos os sites daquele servidor, incluindo wp-config.php e config.php com senha de banco.
No PHP-FPM, o padrão saudável é um pool por site, cada um com seu usuário Linux. A invasão de um site fica contida nas permissões daquele usuário. É o mesmo princípio de menor privilégio que eu defendo no checklist de hardening de servidor Linux.
O que o PHP-FPM não resolve
Aqui mora a armadilha comercial: tem gente vendendo "migre para FPM e fique seguro". Não é verdade.
- O FPM continua vulnerável sem o patch. O aviso oficial lista o PHP-FPM entre os afetados.
- A Datadog explica que um pool maior reduz a chance de sucesso por tentativa, mas não elimina a falha, e que atacantes tentam ocupar todos os processos menos um para cair sempre no mesmo.
- O exploit bem-sucedido não derruba necessariamente o processo. O ataque pode gerar só dois a quatro erros de memória e depois ficar em silêncio.
A ordem é sempre: patch primeiro, arquitetura depois.
Desempenho e consumo de memória
Saindo do incidente, a escolha entre mod_php ou PHP-FPM também pesa no bolso, porque define quanto servidor você precisa.
Prefork contra event
Com mod_php, o Apache roda em prefork: um processo por conexão, cada um com o PHP carregado. Conexões lentas, keep-alive e arquivos estáticos ocupam processos pesados.
Com PHP-FPM, o Apache pode usar o MPM event, que é o padrão desde o Apache 2.4, como lembra o manual do PHP. O event atende muitas conexões com poucas threads leves, e só o que é PHP vai para o pool. O manual chega a chamar o MPM com threads de "recomendado para melhor desempenho sob carga".
Onde o FPM ganha na operação
- Reiniciar o PHP sem reiniciar o Apache. Aplicar patch, mudar
php.iniou matar um processo travado afeta só o PHP. Isso conta muito numa semana como esta, em que o PHP pede para reiniciar todos os workers depois do patch. - Limites por site. Um site com plugin problemático não consome todos os processos do servidor, porque o pool dele tem teto próprio em
pm.max_children. - Diagnóstico.
request_slowlog_timeoutgrava o backtrace de requisições lentas, epm.status_pathmostra em tempo real quantos processos estão ocupados. - Várias versões de PHP lado a lado. Um pool em 8.3 e outro em 8.4 no mesmo servidor, coisa que o mod_php não faz.
Onde o mod_php ainda "ganha"
Sendo justo: na balança mod_php ou PHP-FPM o mod_php tem menos peças. Não há socket, não há segundo serviço para monitorar e o .htaccess com php_value funciona direto. Em servidor de laboratório com um único site e tráfego mínimo, a diferença de desempenho é pequena. Só que, depois do PHP2Shell, simplicidade não compensa ficar no cenário de maior risco.
Tabela comparativa: mod_php ou PHP-FPM
O resumo da comparação mod_php ou PHP-FPM nos critérios que pesam na operação de um servidor de produção:
| Critério | mod_php (Apache) | PHP-FPM |
|---|---|---|
| Onde o PHP roda | Dentro de cada processo do Apache | Serviço separado, com pools |
| MPM do Apache | Prefork (sem ZTS) | Event (padrão do Apache 2.4) |
| Risco no PHP2Shell, segundo o PHP | O maior: exploit antes do código da aplicação | Afetado; no caminho de upload da 109619, depende de operação da aplicação |
| Usuário de execução | Um só (usuário do Apache) para todos os sites | Um por pool, isolando sites |
| Reiniciar o PHP | Reinicia o Apache inteiro | Reinicia só o FPM (ou um pool) |
| Várias versões de PHP | Não | Sim, um pool por versão |
| Limite de processos por site | Não | pm.max_children por pool |
| Configuração por diretório | php_value no .htaccess |
.user.ini ou php_admin_value no pool |
| Recomendação do manual do PHP | Não usar em instalações novas | Recomendado para implantações modernas |
| Suporte em Nginx | Não existe | Padrão |
Como descobrir o que o seu servidor usa hoje
Antes de decidir entre mod_php ou PHP-FPM no seu caso, confirme o modo atual. Três jeitos, do mais rápido ao mais completo:
- Pelo Apache. Rode
apachectl -M | grep -i php. Se aparecerphp_module(ouphp7_module,php8_module), o mod_php está carregado. - Pelo MPM. Rode
apachectl -V | grep -i mpm.preforké forte indício de mod_php;eventindica que o PHP está fora do Apache. - Por um
phpinfo()temporário. O campo Server API mostraApache 2.0 Handler(mod_php) ouFPM/FastCGI. Apague o arquivo logo em seguida:phpinfo()exposto entrega versão e caminhos para quem está varrendo a internet.
Aproveite para anotar a versão exata do PHP. Se ela estiver abaixo de 8.5.12, 8.4.27, 8.3.36 ou 8.2.35 (ou do pacote corrigido da sua distribuição), o problema urgente é esse, não a arquitetura.
Como migrar de mod_php para PHP-FPM sem derrubar o site
Se a resposta para mod_php ou PHP-FPM no seu servidor é migrar, o roteiro abaixo vale para Debian e Ubuntu com Apache 2.4, que é o cenário mais comum que encontramos. Troque 8.3 pela sua versão.
Passo 0: patch antes de tudo
Atualize o PHP para a versão corrigida da sua distribuição e reinicie o Apache. Isso já fecha a janela do PHP2Shell no mod_php. A migração vem depois, em janela planejada. Se você ainda não fez isso, este é o único passo que importa hoje. A dúvida mod_php ou PHP-FPM pode esperar alguns dias; o patch não. No post sobre como proteger o servidor web contra ataques eu explico as camadas de WAF e rate limit que ajudam enquanto isso, sem substituir a correção.
Passo 1: instalar o FPM e criar o pool
Instale o php8.3-fpm com as mesmas extensões que o mod_php usa (compare php -m antes e depois). Crie um pool por site em /etc/php/8.3/fpm/pool.d/, com usuário próprio, socket próprio e limites:
useregroupdo site, nãowww-datalisten = /run/php/site1.sockpm = dynamicepm.max_childrencalculado pela memória (próximo passo)pm.max_requests = 500, para reciclar processos periodicamenterequest_terminate_timeoutcoerente com omax_execution_timephp_admin_value[session.upload_progress.enabled] = 0, se a aplicação não usa barra de progresso de upload
Esse último item vem do aviso oficial: ele bloqueia os caminhos de sessão confirmados da CVE-2026-109619, mas não outras variantes. O PHP pede para aplicar em php.ini, no pool do FPM ou na configuração do servidor, e para não confiar em ini_set() nem em .user.ini.
Passo 2: dimensionar o pool
A conta básica é pm.max_children = memória disponível para o PHP ÷ memória média por processo. Meça o consumo real com ps durante o horário de pico, não use o memory_limit como estimativa. Pool pequeno demais gera fila e erro 503; grande demais leva o servidor a usar swap.
Se o servidor roda Moodle, a conta muda bastante entre horário normal e semana de prova. Os números de referência estão no guia de requisitos de servidor para Moodle 5.x.
Passo 3: trocar o Apache de modo
No Debian/Ubuntu, a sequência típica é:
a2enmod proxy_fcgi setenvifa2enconf php8.3-fpm(ou umSetHandler "proxy:unix:/run/php/site1.sock|fcgi://localhost"no vhost, para pool por site)a2dismod php8.3a2dismod mpm_preforkea2enmod mpm_eventapachectl configteste, se estiver tudo certo,systemctl restart apache2
A troca derruba as conexões por poucos segundos. Faça em horário de baixo tráfego e tenha o caminho de volta anotado: os mesmos comandos, invertidos.
Passo 4: as armadilhas que quebram o site
php_valueephp_flagno.htaccess. Essas diretivas só existem no mod_php. No FPM, o Apache devolve erro 500. Mova os valores para o pool (php_admin_value) ou para.user.ini.- Permissões de arquivo. Com o usuário novo do pool, pastas de upload e cache que pertenciam a
www-datadeixam de ser graváveis. Ajuste o dono antes da troca. - Variáveis de ambiente e autenticação HTTP. Algumas aplicações leem cabeçalhos de autorização de um jeito que muda no FastCGI. Teste login e integrações de API.
- Timeouts. O
ProxyTimeoutdo Apache precisa ser maior que o tempo das tarefas longas, como relatórios e importações.
Passo 5: validar e monitorar
Confirme no phpinfo() temporário que o Server API virou FPM, rode os fluxos críticos (login, checkout, upload, cron) e acompanhe o slowlog e a página de status do pool nas primeiras 48 horas. Só considere a troca de mod_php ou PHP-FPM concluída depois desse período sem alerta.
Quando não migrar agora
Na decisão mod_php ou PHP-FPM a resposta de longo prazo é o FPM, mas há momentos em que fazer isso agora é erro.
- Quando o PHP ainda não foi atualizado. Migrar um PHP vulnerável para FPM troca o cenário de maior risco por um cenário ainda vulnerável. Patch primeiro.
- Quando o servidor roda PHP 7.3 ou mais antigo. Para as versões 5.4 a 7.3 não há correção do projeto, e para 7.4 a 8.1 existem só backports mínimos de código-fonte, segundo a Tenable. Aqui o projeto é atualizar o PHP e a aplicação. A CISA recomenda tirar do ar sistemas PHP que não podem ser atualizados ou que rodam 8.1 ou anterior.
- Quando o servidor é gerenciado por painel. cPanel, Plesk e HestiaCP têm o próprio jeito de trocar o modo PHP por domínio. Mexer à mão no Apache pode ser desfeito na próxima atualização do painel. Use a opção do painel.
- No meio de um período crítico. Semana de matrícula, campanha de vendas ou prova no AVA não é hora de trocar arquitetura. Atualize o PHP, aplique as mitigações oficiais e agende a migração.
E um ponto sobre as mitigações: memory_limit=-1, session.upload_progress.enabled=0 e, no PHP 8.5, fatal_error_backtraces=0 reduzem caminhos de ataque específicos. O PHP diz textualmente que elas não deixam a instalação segura e que atualizar é a única escolha segura. Em 23/10 saiu ainda um terceiro alerta, a CVE-2026-115560, ligado ao upload progress de sessão. O vetor é improvável: exige que a aplicação troque o session.serialize_handler em tempo de execução. A correção vem na próxima versão regular, e a recomendação é manter session.upload_progress.enabled=0 até lá.
Como a Agathas Web resolve isso
Eu administro servidores Linux com PHP desde 2008: Moodle de instituições de ensino, WordPress, Laravel e sistemas que conversam com a API oficial do WhatsApp. A pergunta mod_php ou PHP-FPM, para mim, tem resposta padrão há anos: FPM, um pool por aplicação, cada um com seu usuário. O PHP2Shell só deixou claro por que isso importa.
Na hospedagem gerenciada da Agathas Web, o que está incluso para um cenário como este:
- Atualização do runtime PHP em janela combinada, com teste em staging antes, como parte da rotina de patches de sistema operacional, PHP e banco.
- Arquitetura revisada: diagnóstico do modo atual (mod_php, FPM, painel), plano de migração para PHP-FPM com pools isolados, dimensionamento de
pm.max_childrencom base no consumo real e plano de volta. - Camadas de proteção já previstas no serviço: WAF da Cloudflare, fail2ban e hardening do sistema operacional, para reduzir exposição enquanto um patch é aplicado.
- Monitoramento 24/7 com alertas no WhatsApp da equipe técnica, para enxergar sinais como rajadas de erro de memória e processos do PHP abrindo shell.
- Resposta a incidentes com plano documentado, e backups verificados com restauração testada.
Como funciona: você nos dá acesso ao servidor (ou começamos por uma migração para infraestrutura nova), fazemos o inventário de versões e modos de PHP, apresentamos o plano com janela e rollback, e executamos com a sua aprovação por escrito. A migração do fornecedor atual entra no setup. Para contratar, fale com a equipe pela página de hospedagem gerenciada e conte quantos sites e quais aplicações rodam no servidor.
Conclusão: mod_php ou PHP-FPM, a resposta ficou simples
Para servidor que atende internet, a resposta para mod_php ou PHP-FPM é PHP-FPM, com um pool isolado por site. O manual do PHP já desaconselhava o mod_php em instalações novas por desempenho e operação, e o PHP2Shell acrescentou o argumento de segurança: é o cenário que a própria equipe do PHP aponta como o de maior risco.
Só não inverta a ordem. Primeiro, PHP atualizado para 8.5.12, 8.4.27, 8.3.36, 8.2.35 ou o pacote corrigido da distribuição, com todos os workers reiniciados. Depois, a migração planejada, com teste e caminho de volta. E lembre que o PHP 8.2 chega ao fim de vida em 31/12/2026: se o seu servidor está nele, vale casar a migração para FPM com a atualização de versão.
Se você não tem um sysadmin para fazer isso agora, a hospedagem gerenciada da Agathas Web assume o patch, a migração e o monitoramento.
Fontes: aviso de segurança e arquivo de notícias do PHP, manual do PHP sobre Apache, configuração do PHP-FPM, Tenable, Unit 42, Datadog Security Labs, Huntress, watchTowr e Help Net Security.
Perguntas frequentes
O PHP-FPM é imune ao PHP2Shell?
Não. O aviso oficial do PHP lista o PHP-FPM entre as instalações afetadas, ao lado de Apache com mod_php, php-cgi, FrankenPHP e LiteSpeed. A diferença é de grau: o PHP considera o risco maior no mod_php, onde o exploit demonstrado dispara antes de qualquer código da aplicação. No FPM, segundo a análise da Datadog, o caminho de upload da CVE-2026-109619 também exige que a aplicação faça uma operação específica depois da inicialização. Por isso a proteção real é atualizar para 8.5.12, 8.4.27, 8.3.36 ou 8.2.35 (ou o pacote corrigido da distribuição) e reiniciar todos os workers. A migração para FPM vem depois, como melhoria de arquitetura.
Como saber se meu servidor usa mod_php ou PHP-FPM?
No Apache, rode apachectl -M e procure por php_module, php7_module ou php8_module: se aparecer, o mod_php está carregado. O comando apachectl -V mostra o MPM; prefork costuma indicar mod_php, event indica PHP fora do Apache. Outra forma é criar um phpinfo() temporário e ver o campo Server API: Apache 2.0 Handler é mod_php, FPM/FastCGI é PHP-FPM. Apague o arquivo logo depois, porque ele expõe versão e caminhos do servidor. Se o site roda em Nginx, ele já usa PHP-FPM ou outro processo FastCGI.
Migrar para PHP-FPM derruba o site?
A troca em si causa uma queda de poucos segundos, no reinício do Apache. O que derruba site de verdade são as armadilhas: diretivas php_value e php_flag no .htaccess, que só existem no mod_php e passam a gerar erro 500; permissões de pastas de upload e cache que deixam de ser graváveis com o novo usuário do pool; e timeouts menores que tarefas longas. Com um inventário dessas configurações, teste em staging, janela de baixo tráfego e os comandos de volta anotados, a migração costuma ser tranquila. Em servidores com cPanel, Plesk ou HestiaCP, use a opção do próprio painel.
As mitigações de configuração bastam se eu não puder atualizar o PHP?
Não. O PHP afirma que não há mitigação completa e que atualizar é a única escolha segura. memory_limit=-1 remove a falha de limite de memória controlável, mas uma falha de alocação ainda pode alcançar o caminho vulnerável. session.upload_progress.enabled=0 bloqueia os caminhos de sessão confirmados, não outras variantes, e fatal_error_backtraces=0 só vale para o PHP 8.5. Essas medidas compram tempo. Para versões 5.4 a 7.3 não há correção, e a CISA recomenda tirar do ar sistemas PHP que não podem ser atualizados ou que rodam 8.1 ou anterior.
Posts relacionados

Resposta a Incidente PHP: Foi Invadido via PHP2Shell?
Atualizou o PHP? Ótimo, mas o patch não diz se alguém entrou entre 17 e 21/10. Veja como checar, conter e trocar credenciais.

Quem aplica patch PHP hospedagem compartilhada, VPS ou gerenciada no PHP2Shell
O PHP2Shell já tem correção, mas ela só vale quando alguém instala e reinicia. Veja quem faz isso no seu tipo de hospedagem.

PHP2Shell SaaS: o Risco de Vazamento Entre Clientes no PHP-FPM
Em SaaS multi-tenant, o worker que atendeu um cliente atende o próximo. Veja por que o PHP2Shell ameaça o isolamento e o que fazer.