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 →

Filtrar pedidos de upload na periferia: oportunidades e riscos

Autores especializados propõem bloquear no proxy os pedidos de upload fora dos caminhos de upload reais até o PHP ser corrigido. Pode ajudar, mas também paralisar formulários e encomendas. Como proceder de forma controlada.

Atualizado em 6 min de leituraHardening e configuração

Em resumo: Filtrar pedidos de upload na periferia significa rejeitar no proxy, no servidor web ou na WAF os pedidos POST do tipo multipart/form-data que não se dirijam a um caminho de upload conhecido. Autores especializados propõem-no como medida temporária e não oficial contra o PHP2Shell. Pode interromper formulários e uploads e nunca substitui a atualização. Proceda em três passos: registar, definir exceções e só depois bloquear, com uma data de fim fixa.

Uma proposta da discussão especializada

Até um servidor ser corrigido, os operadores procuram tudo o que reduza o risco. Na discussão especializada sobre o PHP2Shell surgiu uma proposta: permitir os pedidos POST no formato multipart/form-data, ou seja, o formato dos uploads de ficheiros e de alguns formulários, apenas onde a aplicação realmente os espera. Todos os outros são rejeitados no proxy ou na Web Application Firewall.

É importante o enquadramento. A proposta não vem do php.net, mas de autores especializados, e destina-se expressamente a ser uma medida temporária. O php.net indica medidas transitórias próprias, reunidas em Medidas imediatas, quando ainda não pode aplicar o patch. O filtro pode complementá-las, não substituí-las.

Descrevemos aqui como o introduzir de forma controlada. Os pormenores sobre por que razão poderia ajudar contra que ataques, omitimo-los deliberadamente.

O que o filtro faz e onde prejudica

A ideia por trás é uma redução da superfície de ataque. A maioria das páginas de um site não precisa de uploads de ficheiros. Se apenas poucos caminhos conhecidos aceitarem esses pedidos, uma grande parte das possíveis tentativas de ataque nem sequer chega ao PHP.

O reverso é igualmente claro. Qualquer função que envie pedidos multipart e não conste da lista de exceções deixa de funcionar. Isto não afeta apenas os formulários de upload óbvios.

Função Usa muitas vezes multipart/form-data Risco ao bloquear
Formulários de contacto e de candidatura com anexo sim os pedidos perdem-se
Gestão de multimédia no backend do CMS sim a redação não consegue carregar imagens
Importação de produtos ou clientes sim as interfaces falham em silêncio
Formulários sem anexo por vezes depende do construtor de formulários
Interfaces e retornos de serviços externos raramente, mas possível a falha só é notada tarde

Acresce um problema de fundo: a Cloudflare, que lançou ela própria regras de proteção contra o PHP2Shell, alerta que as regras baseadas apenas nos dados do pedido não bastam. Como pensar os dois níveis em conjunto é descrito em WAF ou atualização: por que precisa de ambas.

Passo 1: primeiro registar, depois bloquear

Antes de bloquear algo, descubra que caminhos recebem sequer pedidos multipart. Os registos padrão não mostram o tipo de conteúdo. Para o Nginx, crie por isso temporariamente um registo próprio:

# no bloco http
map $uri $upload_pfad {
    default 0;
    ~^/kontakt/upload\.php$ 1;
    ~^/admin/medien/ 1;
}

map "$request_method:$upload_pfad:$content_type" $multipart_fremd {
    default 0;
    "~*^POST:0:multipart/form-data" 1;
}

log_format multipart '$time_iso8601 $remote_addr "$request" "$content_type" $status';

# no bloco server
# Atenção: um access_log no bloco server substitui o registo herdado,
# por isso volte a indicar aqui o registo normal.
access_log /var/log/nginx/access.log combined;
access_log /var/log/nginx/multipart-test.log multipart if=$multipart_fremd;

As entradas em $upload_pfad são exemplos. Comece com uma lista de exceções vazia; então o registo de teste mostra todos os POST multipart. No Apache, o mesmo consegue-se com uma variável de ambiente:

# no VirtualHost
SetEnvIfNoCase Content-Type "^multipart/form-data" ist_multipart
CustomLog ${APACHE_LOG_DIR}/multipart-test.log combined env=ist_multipart

Deixe o registo correr alguns dias, idealmente durante um período em que também a redação, os candidatos e as interfaces estivessem ativos.

Passo 2: definir exceções e bloquear de forma controlada

A partir do registo de teste, deduza os caminhos que legitimamente precisam de uploads. Compare a lista com os responsáveis: quem mantém conteúdos, que formulários existem, que serviços enviam dados?

  1. Elaborar a lista de exceções a partir do registo e de perguntas e registá-la em $upload_pfad ou nas linhas RewriteCond.
  2. Ativar o filtro primeiro num ambiente de teste ou numa janela de tempo calma.
  3. Percorrer pessoalmente todos os formulários, uploads e percursos de encomenda.
  4. Monitorizar no registo de erros os pedidos rejeitados (estado 403) e completar a lista se necessário.
  5. Fixar uma data de fim: após a atualização do PHP e o reinício de todos os workers, o filtro volta a ser removido.

No Nginx, acrescente para isso o bloqueio no bloco server:

# no bloco server, depois de avaliada a fase de registo
if ($multipart_fremd) {
    return 403;
}

No Apache, o mod_rewrite assume a tarefa. Segundo a documentação do Apache, várias condições são ligadas com E:

RewriteEngine On
RewriteCond %{REQUEST_METHOD} =POST
RewriteCond %{HTTP:Content-Type} ^multipart/form-data [NC]
RewriteCond %{REQUEST_URI} !^/kontakt/upload\.php$
RewriteCond %{REQUEST_URI} !^/admin/medien/
RewriteRule ^ - [F]

Se usar uma CDN ou uma WAF na nuvem, a mesma lógica pode muitas vezes ser reproduzida como regra própria. Também aí vale: primeiro em modo de registo, depois bloquear.

Importante

O filtro não substitui a atualização do PHP e não é motivo para a adiar. O PHP2Shell só fica corrigido com PHP 8.5.12, 8.4.27, 8.3.36, 8.2.35 ou um backport confirmado, seguido do reinício de todos os processos PHP.

Enquadrar corretamente a medida

O filtro de uploads pertence a uma série de outras propostas que circulam atualmente. Algumas são sensatas, outras prejudiciais. Uma visão geral das dicas que os autores especializados rejeitam, por exemplo o bloqueio de todos os pedidos com cookie de sessão, é dada em Falsas dicas perigosas sobre o PHP2Shell.

Como o PHP processa uploads internamente e por que razão o formato multipart/form-data desempenha aí um papel especial é explicado em Como o PHP processa uploads de ficheiros. Para a maioria das empresas, o passo mais importante não é, no entanto, o filtro, mas uma data clara para a atualização.

Conclusão: uma ferramenta para dias, não para meses

O filtro de uploads na periferia é um exemplo típico de uma medida de emergência: pode reduzir a superfície de ataque na fase transitória, mas tem efeitos secundários e não tem respaldo oficial do php.net. Corretamente aplicado, com fase de registo, lista de exceções acordada, testes e data de fim fixa, é defensável. Sem estes passos, arrisca-se a perder candidaturas, a bloquear redações e a ter falhas silenciosas nas interfaces.

Tome por isso a decisão de forma consciente e registe quem a tomou e quando. E tenha presente a ordem: primeiro vem a atualização do PHP com reinício de todos os workers, as medidas transitórias do php.net colmatam o tempo até lá e o filtro é, quando muito, uma camada adicional.

Como ajuda concretamente a PHP SOS?

  • Avaliar a situação: esclarecemos se um filtro de uploads faz sequer sentido na sua situação ou se a atualização é possível mais depressa.
  • Registar e analisar: configuramos a fase de registo e deduzimos a lista de exceções a partir de acessos reais.
  • Bloquear de forma controlada: ativamos o filtro, testamos formulários e percursos de encomenda e monitorizamos os pedidos rejeitados.
  • Desmontar corretamente: no âmbito de WAF e patching virtual, removemos o filtro depois da atualização.

Perguntas frequentes

Filtrar pedidos multipart é uma recomendação oficial do php.net?

Não. O php.net indica outras medidas transitórias, por exemplo limites para o post_max_size e a desativação do session.upload_progress. Filtrar na periferia é uma proposta de artigos especializados e destina-se expressamente apenas como medida temporária.

Que funções podem falhar por causa do filtro?

Tudo o que envia ficheiros ou formulários em formato multipart e não consta da sua lista de exceções: formulários de contacto com anexo, formulários de candidatura, gestão de multimédia no CMS, funções de importação, algumas interfaces e retornos de pagamento. Por isso, antes do bloqueio vem uma fase de registo.

O filtro substitui a atualização do PHP?

Não. No máximo, reduz a superfície de ataque na fase transitória. A própria Cloudflare alerta que regras baseadas apenas nos dados do pedido não bastam. O PHP2Shell só fica corrigido com uma versão corrigida do PHP e o reinício de todos os workers.

Devo, em vez disso, bloquear pedidos com PHPSESSID?

Não. Esta dica em circulação é expressamente rejeitada por autores especializados. Paralisa inícios de sessão e carrinhos de compras sem oferecer uma proteção fiável.

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