In breve: filtrare le richieste di upload al perimetro significa rifiutare su proxy, server web o WAF le richieste POST di tipo multipart/form-data se non sono dirette a un percorso di upload noto. Autori specializzati lo propongono come misura temporanea e non ufficiale contro PHP2Shell. Può rompere moduli e upload e non sostituisce mai l'aggiornamento. Proceda in tre passi: registrare, definire le eccezioni, solo poi bloccare, con una data di fine fissa.
Una proposta dalla discussione specializzata
Finché un server non è aggiornato con la patch, i gestori cercano tutto ciò che riduce il rischio. Nella discussione specializzata su PHP2Shell è comparsa una proposta: consentire le richieste POST nel formato multipart/form-data, cioè il formato per gli upload di file e alcuni moduli, solo dove l'applicazione le attende davvero. Tutte le altre vengono respinte sul proxy o nella Web Application Firewall.
Importante è l'inquadramento. La proposta non proviene da php.net, ma da autori specializzati, ed è espressamente pensata come misura temporanea. php.net indica proprie misure transitorie, raccolte in Misure immediate se non può ancora applicare la patch. Il filtro può integrarle, non sostituirle.
Descriviamo qui come introdurlo in modo controllato. I dettagli sul perché potrebbe aiutare contro quali attacchi li omettiamo volutamente.
Che cosa ottiene il filtro e dove danneggia
L'idea di fondo è una riduzione della superficie d'attacco. La maggior parte delle pagine di un sito non ha bisogno di upload di file. Se solo pochi percorsi noti accettano tali richieste, gran parte dei possibili tentativi di attacco non raggiunge più PHP.
Il rovescio è altrettanto chiaro. Ogni funzione che invia richieste multipart e manca nella lista di eccezioni va fuori uso. Ciò riguarda non solo i moduli di upload evidenti.
| Funzione | Usa spesso multipart/form-data | Rischio in caso di blocco |
|---|---|---|
| Moduli di contatto e di candidatura con allegato | sì | le richieste vanno perse |
| Gestione dei media nel backend del CMS | sì | la redazione non può caricare immagini |
| Importazione di prodotti o clienti | sì | le interfacce si rompono in silenzio |
| Moduli senza allegato | a volte | dipende dal costruttore di moduli |
| Interfacce e ritorni di servizi esterni | raramente, ma possibile | il guasto si nota tardi |
Si aggiunge un problema di fondo: Cloudflare, che ha esso stesso distribuito regole di protezione contro PHP2Shell, avverte che le regole basate solo sui dati della richiesta non bastano. Come considerare insieme i due livelli lo descrive WAF o aggiornamento: perché servono entrambi.
Passo 1: prima registrare, poi bloccare
Prima di bloccare qualsiasi cosa, scopra quali percorsi ricevano in generale richieste multipart. I log standard non mostrano il tipo di contenuto. Per Nginx crei quindi temporaneamente un registro proprio:
# nel blocco 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';
# nel blocco server
# Attenzione: un access_log nel blocco server sostituisce il registro ereditato,
# quindi indicare qui di nuovo il log normale.
access_log /var/log/nginx/access.log combined;
access_log /var/log/nginx/multipart-test.log multipart if=$multipart_fremd;
Le voci in $upload_pfad sono esempi. Parta con una lista di eccezioni vuota, così il registro di prova mostra tutti i POST multipart. Sotto Apache lo stesso si ottiene con una variabile d'ambiente:
# nel VirtualHost
SetEnvIfNoCase Content-Type "^multipart/form-data" ist_multipart
CustomLog ${APACHE_LOG_DIR}/multipart-test.log combined env=ist_multipart
Lasci girare il registro per alcuni giorni, idealmente per un periodo in cui siano stati attivi anche redazione, candidati e interfacce.
Passo 2: definire le eccezioni e bloccare in modo controllato
Dal registro di prova ricavi i percorsi che hanno legittimamente bisogno di upload. Confronti l'elenco con i responsabili: chi cura i contenuti, quali moduli esistono, quali servizi inviano dati?
- Creare la lista di eccezioni da registro e richieste e inserirla in
$upload_pfado nelle righeRewriteCond. - Attivare il filtro prima su un ambiente di test o in una fascia oraria tranquilla.
- Provare di persona tutti i moduli, gli upload e i percorsi d'ordine.
- Monitorare il registro degli errori per le richieste respinte (stato 403) e integrare l'elenco se necessario.
- Fissare una data di fine: dopo l'aggiornamento di PHP e il riavvio di tutti i worker, il filtro viene rimosso di nuovo.
In Nginx aggiunga a tal fine il blocco nel blocco server:
# nel blocco server, dopo la valutazione della fase di registrazione
if ($multipart_fremd) {
return 403;
}
In Apache se ne occupa mod_rewrite. Secondo la documentazione di Apache, più condizioni sono collegate con AND:
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 usa una CDN o una WAF cloud, la stessa logica si può spesso riprodurre come regola propria. Anche lì vale: prima in modalità registrazione, poi bloccare.
Il filtro non è un sostituto dell'aggiornamento di PHP e non è un motivo per rimandarlo. PHP2Shell è corretto solo con PHP 8.5.12, 8.4.27, 8.3.36, 8.2.35 o con un backport confermato, seguito dal riavvio di tutti i processi PHP.
Inquadrare correttamente la misura
Il filtro degli upload si colloca accanto ad altre proposte che attualmente circolano. Alcune sono sensate, altre dannose. Un panoramica di quali consigli gli autori specializzati respingano, ad esempio il blocco di tutte le richieste con cookie di sessione, la offre Consigli sbagliati e pericolosi su PHP2Shell.
Come PHP elabora internamente gli upload e perché il formato multipart/form-data vi svolga un ruolo particolare lo spiega Come PHP elabora gli upload di file. Per la maggior parte delle aziende, però, il passo più importante non è il filtro, ma una data chiara per l'aggiornamento.
Conclusione: uno strumento per giorni, non per mesi
Il filtro degli upload al perimetro è un tipico esempio di misura d'emergenza: può ridurre la superficie d'attacco nel periodo transitorio, ma ha effetti collaterali e nessun sostegno ufficiale da parte di php.net. Impiegato correttamente, con fase di registrazione, lista di eccezioni concordata, test e data di fine fissa, è accettabile. Senza questi passi si rischiano candidature perdute, redazioni bloccate ed errori silenziosi delle interfacce.
Prenda quindi la decisione in modo consapevole e annoti chi l'ha presa e quando. E tenga presente l'ordine: prima viene l'aggiornamento di PHP con il riavvio di tutti i worker, le misure transitorie di php.net coprono il tempo fino ad allora e il filtro è al massimo un livello aggiuntivo.
Come aiuta PHP SOS in concreto?
- Valutare la situazione: chiariamo se un filtro degli upload abbia senso nella Sua situazione o se l'aggiornamento sia possibile più rapidamente.
- Registrare e analizzare: configuriamo la fase di registrazione e ricaviamo la lista di eccezioni da accessi reali.
- Bloccare in modo controllato: attiviamo il filtro, testiamo moduli e percorsi d'ordine e monitoriamo le richieste respinte.
- Smontare in modo pulito: nell'ambito di WAF e virtual patching rimuoviamo di nuovo il filtro dopo l'aggiornamento.
Domande frequenti
Filtrare le richieste multipart è una raccomandazione ufficiale di php.net?
No. php.net indica altre misure transitorie, ad esempio limiti per post_max_size e la disattivazione di session.upload_progress. Il filtro al perimetro è una proposta tratta da contributi specializzati ed è espressamente pensato solo come misura temporanea.
Quali funzioni possono venire a mancare a causa del filtro?
Tutto ciò che invia file o moduli in formato multipart e non è nella Sua lista di eccezioni: moduli di contatto con allegato, moduli di candidatura, gestione dei media nel CMS, funzioni di importazione, alcune interfacce e ritorni di pagamento. Per questo prima del blocco c'è una fase di registrazione.
Il filtro sostituisce l'aggiornamento di PHP?
No. Al massimo riduce la superficie d'attacco nel periodo transitorio. Cloudflare stesso fa notare che le regole basate solo sui dati della richiesta non bastano. PHP2Shell è corretto solo con una versione di PHP con patch e il riavvio di tutti i worker.
Devo invece bloccare le richieste con PHPSESSID?
No. Questo consiglio che circola è espressamente respinto dagli autori specializzati. Paralizza login e carrelli senza offrire una protezione affidabile.