# Proteger o FrankenPHP

> Segurança FrankenPHP após o PHP2Shell: verificar a versão PHP incorporada, recompilar binário ou imagem, reiniciar bem os workers e reforçar os valores.

Fonte: https://phpsos.de/pt/server/frankenphp/  
Atualizado em: 25/10/2026  
Prestador: PHP SOS, Assistência de emergência PHP e segurança de servidores. Ajuda imediata por WhatsApp: https://wa.me/491736494914?text=Ol%C3%A1%2C%20PHP%20SOS%2C%20precisamos%20de%20ajuda%20com%20o%20nosso%20servidor%20PHP.%20Empresa%3A%20%E2%80%A6%20Site%3A%20%E2%80%A6

**Em resumo:** o FrankenPHP é um servidor de aplicações baseado no Caddy que incorpora o PHP no seu próprio programa. Para a segurança do FrankenPHP após o PHP2Shell, isto significa: não contam os pacotes PHP da distribuição, mas a versão PHP dentro do binário do FrankenPHP ou da imagem de contentor. Compile ou obtenha uma versão com o PHP corrigido e reinicie todos os workers.

## Porque é que o FrankenPHP leva patches de outra forma

Nas configurações clássicas, a distribuição fornece o PHP como pacote, e uma atualização troca os ficheiros. O FrankenPHP, pelo contrário, contém o PHP como biblioteca incorporada. Quem usa o binário oficial ou uma imagem de contentor baseada nele recebe o PHP já incluído. Um `apt upgrade` no anfitrião não altera nada nisso.

O PHP2Shell engloba a CVE-2026-109618 e a CVE-2026-109619, cada uma com CVSS v4.0 9.2. O projeto PHP indica expressamente o FrankenPHP entre os modos de operação afetados. Estão corrigidos o PHP 8.5.12, 8.4.27, 8.3.36 e 8.2.35. O decisivo é, portanto, com que versão PHP o seu FrankenPHP foi compilado.

## Modo worker e PHP2Shell

O FrankenPHP pode operar aplicações em modo worker. A aplicação é carregada uma vez e trata depois muitos pedidos seguidos no mesmo processo. Isso traz velocidade, mas prolonga a duração de vida de cada processo.

A CVE-2026-109619 descreve estado interno de um pedido que pode persistir depois de a memória ser libertada; um pedido posterior no mesmo worker pode usá-lo antes de ser reposto. No modo worker, a interação de muitos pedidos num só processo é o caso normal. Isso não é motivo para prescindir do modo worker, mas é um motivo claro para executar atualizações e reinícios com especial cuidado. Os pormenores técnicos estão em [CVE-2026-109619](https://phpsos.de/pt/php2shell/cve-2026-109619/).

## Segurança do FrankenPHP: verificar a versão

Verifique a versão PHP incorporada diretamente no sistema em execução. Os comandos seguintes apenas leem; os nomes de serviços e de contentores são exemplos.

```bash
# Binário instalado
frankenphp version

# No contentor em execução (nome do contentor como exemplo)
docker exec app frankenphp version
docker exec app php -v

# Que imagem está realmente a correr? (o digest mostra o nível exato)
docker inspect --format '{{.Image}} {{.Config.Image}}' app
```

Anote a versão PHP que aparece na saída. Se for anterior aos níveis corrigidos, o sistema está vulnerável. Verifique sempre o contentor em execução, não apenas a última imagem compilada, porque uma imagem nova só produz efeito depois de os contentores serem substituídos.

## Instalar a atualização e reiniciar todos os workers

Como é a atualização depende da sua instalação:

- **Binário no anfitrião:** instalar uma nova versão do FrankenPHP com a versão PHP corrigida e reiniciar o serviço.
- **Contentor:** obter a imagem de base com a versão PHP corrigida, recompilar a imagem própria, sem cache para a camada de base, e substituir o contentor.
- **Compilado por si:** recompilar com a versão PHP corrigida e regenerar todas as extensões com a mesma versão.

```bash
# Exemplo de instalação no anfitrião como serviço systemd
systemctl restart frankenphp

# Exemplo Docker Compose: recompilar sem cache e substituir o contentor
docker compose build --pull --no-cache
docker compose up -d --force-recreate
```

Depois, verifique de novo a versão PHP no contentor em execução e a hora de arranque dos processos. No modo worker, todos os workers têm de ter sido reiniciados. No Kubernetes aplicam-se passos adicionais, descritos em [Aplicar patch ao PHP no Kubernetes](https://phpsos.de/pt/server/kubernetes/); para contentores em geral, em [Aplicar patch ao PHP em contentores Docker](https://phpsos.de/pt/php2shell/docker-container-patchen/).

> **Importante:**
> Uma etiqueta como `latest` ou uma versão principal no nome da imagem não garante que tem o nível mais recente. Volte a obter ativamente a imagem de base e verifique depois a versão PHP no contentor em execução.

## Medidas provisórias e reforço

Se a atualização não puder ser feita de imediato, o php.net recomenda medidas provisórias que não oferecem proteção completa. No FrankenPHP, defina os valores no php.ini que o FrankenPHP carrega ou através das definições PHP na configuração do Caddy, não com `ini_set()` na aplicação.

```ini
; php.ini no contentor ou no anfitrião
session.upload_progress.enabled = 0
post_max_size = 8M
upload_max_filesize = 6M
```

Com função de upload, o php.net indica `post_max_size = 32M`. No PHP 8.5 acresce `fatal_error_backtraces=0`. O limite de memória pertence ao nível do contentor, por exemplo através do limite de memória do contentor, e não a `RLIMIT_AS` ou `RLIMIT_DATA`. Depois de cada alteração, reinicie todos os workers.

Para a operação contínua, compensa referenciar imagens com digest fixo, recompilá-las regularmente de forma automatizada e incluir um analisador de imagens na cadeia de compilação. Além disso, um patch não remove software malicioso introduzido antes. Guarde os registos a partir de 20/10/2026; nos contentores, isso significa preservá-los antes de os substituir.

Quem usa o FrankenPHP como binário compilado de forma estática deve saber que, nesse caso, além do PHP, também todas as extensões estão integradas de forma fixa. Uma atualização significa por isso sempre substituir o binário inteiro. Depois da troca, verifique a versão e a lista das extensões carregadas, para confirmar que tudo está disponível como antes, e teste a aplicação antes de descartar o nível antigo. Em ambientes de contentores, recomenda-se identificar cada imagem com a data da compilação. Assim pode reconstituir a qualquer momento que nível correu quando e, em caso de dúvida, voltar atrás de forma dirigida sem cair de novo num nível vulnerável. Registe na sua documentação a relação entre imagem, versão PHP e momento.

## Como ajuda concretamente a PHP SOS?

- Verificamos que versão PHP está realmente nos seus binários FrankenPHP e contentores em execução.
- Através do [serviço de patches PHP](https://phpsos.de/pt/leistungen/php-patch-service/), recompilamos imagens, substituímos contentores e reiniciamos todos os workers, com comprovativo.
- Preservamos os registos antes da substituição e verificamos a aplicação quanto a vestígios.
- Para a operação contínua, configuramos recompilações automatizadas e verificações de imagens no âmbito do [reforço de servidores](https://phpsos.de/pt/leistungen/server-haertung/).


## Perguntas frequentes

**Uma atualização com apt ou dnf ajuda no FrankenPHP?**  
Só se o próprio FrankenPHP vier dessas origens de pacotes e estiver compilado com o PHP já corrigido. Muitas vezes o PHP está integrado de forma fixa no binário do FrankenPHP ou na imagem de contentor. Nesse caso tem de atualizar o binário ou a imagem.

**Porque é que o modo worker é particularmente importante no PHP2Shell?**  
No modo worker, a aplicação permanece em memória e trata muitos pedidos em sequência no mesmo processo. A CVE-2026-109619 diz respeito precisamente a estado interno que pode persistir entre pedidos no mesmo worker. Reiniciar todos os workers depois da atualização é por isso obrigatório.

**Como verifico que versão PHP está dentro do FrankenPHP?**  
O binário do FrankenPHP indica a versão PHP incorporada quando é chamado com o comando de versão. Num contentor, pode executar o comando com docker exec. Verifique a versão no contentor que está realmente em execução, não na imagem acabada de compilar.

**Existem medidas provisórias específicas para o FrankenPHP?**  
Aplicam-se as indicações gerais do php.net. Defina os valores no php.ini que o FrankenPHP carrega ou na configuração PHP do ficheiro Caddy, não com ini_set() na aplicação. Depois, reinicie todos os workers.

## Fontes

- [php.net: avisos de segurança](https://www.php.net/)
- [PHP 8 ChangeLog](https://www.php.net/ChangeLog-8.php)
- [OWASP Cheat Sheets](https://cheatsheetseries.owasp.org/)
