Situação atual: PHP2Shell. Duas vulnerabilidades críticas do PHP (CVSS 9,2) permitem executar código malicioso sem autenticação. Patches disponíveis desde 21/10/2026.O que fazer agora →

Como o PHP gera uma página web: o percurso de um pedido

O que acontece entre o clique e a página pronta: servidor web, SAPI, compilador, OPcache e Zend VM em sete passos, e porque é que o PHP2Shell atua precisamente neste percurso.

Atualizado em 5 min de leituraConhecimento PHP

Em resumo: Quando um navegador pede uma página PHP, o servidor web aceita o pedido e passa-o ao PHP através de uma interface (SAPI). O PHP traduz o script para bytecode, executa-o na Zend Engine e devolve o resultado, geralmente HTML, ao servidor web. Depois, o estado do pedido é limpo, para que o seguinte comece em condições limpas.

O que acontece quando alguém acede ao seu site?

Para os visitantes, é um clique. No servidor decorrem muitos passos em milissegundos. Quem conhece este percurso compreende melhor por que razão as atualizações, os reinícios e a configuração são tão importantes e por que razão uma falha no próprio PHP pesa mais do que uma falha num plugin.

O manual do PHP refere três componentes necessários para um site PHP: o interpretador PHP (como CGI ou módulo do servidor), um servidor web e um navegador. O interpretador é o programa que lê e executa o código PHP. A forma como está ligado ao servidor web determina o modo de operação.

Como funciona o PHP? Sete passos de um pedido

  1. Pedido: O navegador envia ao servidor um pedido HTTP, por exemplo GET /kontakt.php.
  2. Servidor web: Apache, Nginx ou LiteSpeed aceitam o pedido. Entregam eles próprios os ficheiros estáticos, como imagens. Para ficheiros .php, chamam o PHP.
  3. Passagem através da SAPI: A interface do servidor (SAPI) passa ao PHP os dados do pedido, como cabeçalhos, parâmetros e dados de formulários. No PHP-FPM isto faz-se através do protocolo FastCGI; no mod_php, diretamente no processo do Apache. Pormenores em SAPI explicada.
  4. Preparar o pedido: O PHP guarda os dados do pedido em variáveis como $_GET, $_POST, $_COOKIE e $_FILES e reserva memória para o pedido.
  5. Traduzir: O script é decomposto em elementos (tokens), daí resulta uma árvore sintática abstrata (AST) e dela os opcodes, uma espécie de linguagem máquina para o PHP. Se o OPcache estiver ativo, este passo é ignorado quando o script já se encontra na cache.
  6. Executar: A máquina virtual da Zend Engine processa os opcodes, consulta bases de dados, lê ficheiros e gera a saída.
  7. Resposta e limpeza: A saída regressa ao servidor web através da SAPI e daí ao navegador. Em seguida, o PHP liberta a memória do pedido e repõe o estado.

A AST existe desde o PHP 7. Segundo o RFC correspondente, antes disso o analisador gerava os opcodes diretamente durante a leitura; a separação em três fases tornou o compilador mais fácil de manter.

Um exemplo: o que o script vê do pedido

O seguinte script inofensivo mostra que informações o PHP recebe do pedido e em que modo de operação corre:

<?php
header('Content-Type: text/plain; charset=utf-8');

echo 'Betriebsart (SAPI): ' . PHP_SAPI . "\n";
echo 'PHP-Version: ' . PHP_VERSION . "\n";
echo 'Methode: ' . ($_SERVER['REQUEST_METHOD'] ?? '-') . "\n";
echo 'Speicher in dieser Anfrage: ' . memory_get_usage() . " Bytes\n";

Num servidor com PHP-FPM, PHP_SAPI devolve o valor fpm-fcgi; no Apache com mod_php, apache2handler. Guarde estes ficheiros de teste apenas por pouco tempo e nunca de forma permanente no diretório público, pois as indicações de versão também ajudam os atacantes a orientar-se.

Onde entram a cache de bytecode e o JIT

A tradução no passo 5 consome tempo. Segundo o manual, o OPcache guarda bytecode pré-compilado na memória partilhada e poupa assim ao PHP o carregamento e a decomposição dos scripts a cada pedido. Desde o PHP 8.0, um compilador JIT pode ainda gerar código máquina real a partir dos opcodes. Segundo o RFC do JIT, é uma parte quase autónoma do OPcache.

Fase Resultado É guardado em cache?
Análise léxica fluxo de tokens não
Análise sintática árvore sintática abstrata (AST) não
Compilação opcodes (op-arrays por ficheiro e função) sim, no OPcache
JIT (opcional) código máquina sim, na memória do OPcache
Execução saída da página não

A cache diz respeito apenas ao código traduzido. Os dados de cada pedido, como entradas de formulários ou valores de sessão, não são partilhados através do OPcache.

Porque é que o PHP2Shell atua precisamente neste percurso

As duas vulnerabilidades do PHP2Shell não dizem respeito a uma aplicação, mas ao próprio percurso. No CVE-2026-109618, uma condição de falta de memória pode interromper o PHP enquanto os dados do pedido estão só parcialmente preparados, ou seja, no passo 4. Na limpeza que se segue, dados inválidos podem então ser tratados como válidos.

No CVE-2026-109619, o estado interno de um pedido pode persistir depois de a memória ser libertada. Um pedido posterior no mesmo worker pode usá-lo antes de ser reposto. Isto diz respeito ao passo 7, a limpeza. Os antecedentes estão na página CVE-2026-109619 e no artigo sobre o ciclo de vida do pedido.

Daqui resulta: as medidas de proteção no código da aplicação, como os plugins de segurança, só atuam no passo 6. No mod_php, segundo a equipa do PHP, chegou a ser demonstrado um exploit antes de qualquer código de aplicação correr. Só é eficaz a atualização do PHP para 8.5.12, 8.4.27, 8.3.36 ou 8.2.35 e o reinício de todos os processos PHP, porque, de outro modo, os workers de longa duração continuam a executar o código antigo.

Como ajuda concretamente a PHP SOS?

  • Tornar o percurso visível: Apuramos que modo de operação, que configuração e que cache estão realmente ativos no seu servidor.
  • Atualizar corretamente: Aplicamos a atualização do PHP e verificamos, através das horas de arranque, que já não corre nenhum processo antigo.
  • Proteger as camadas: No âmbito do reforço de servidores, limitamos tamanhos de pedidos, memória e permissões onde fazem efeito: antes do código da aplicação.
  • Verificar vestígios: Em servidores acessíveis sem proteção, procuramos sinais de intrusão.

Perguntas frequentes

O código PHP é traduzido de novo a cada acesso?

Sem cache, sim: o PHP decompõe o script, constrói uma árvore sintática e gera a partir dela os opcodes. Com o OPcache ativo, os opcodes ficam na memória partilhada e são reutilizados enquanto o ficheiro não for alterado.

O que fica na memória depois de um pedido?

Em princípio, o estado de um pedido é limpo no fim, para que o pedido seguinte comece em condições limpas. Só coisas como o OPcache ou as ligações persistentes têm vida longa. É precisamente nesta limpeza que atua o CVE-2026-109619.

Porque é que o PHP tem de ser reiniciado depois de uma atualização?

No PHP-FPM e no mod_php, os processos correm de forma permanente e têm carregado o código de programa antigo. Novos ficheiros no disco não alteram isso. Só um reinício carrega o código corrigido.

Um servidor web sem PHP é mais seguro?

Tem menos superfície de ataque, porque nenhuma lógica de programa reage aos pedidos. Para conteúdos puramente estáticos, é uma opção real. Para lojas, formulários e autenticações, porém, é preciso uma linguagem do lado do servidor, e então conta a sua manutenção.

Fontes

Contacto imediato

Cada hora conta. Escreva-nos agora.

Descreva brevemente o sistema, a versão do PHP e o que observou. Entramos em contacto consigo, esclarecemos a situação e trabalhamos remotamente até o incidente estar concluído e documentado.

Ajuda imediata