Pe scurt: A filtra cererile de upload la margine înseamnă a respinge, la proxy, în serverul web sau în WAF, cererile POST de tip multipart/form-data care nu merg către o cale de upload cunoscută. Autori de specialitate propun aceasta ca măsură temporară, neoficială, împotriva PHP2Shell. Ea poate strica formulare și upload-uri și nu înlocuiește niciodată actualizarea. Procedați în trei pași: jurnalizați, stabiliți excepțiile, abia apoi blocați, cu o dată de încheiere fixă.
O propunere din discuția de specialitate
Până când un server este patchuit, operatorii caută tot ce reduce riscul. În discuția de specialitate despre PHP2Shell a apărut o propunere: cererile POST în format multipart/form-data, deci formatul pentru încărcări de fișiere și unele formulare, să fie permise doar acolo unde aplicația le așteaptă cu adevărat. Toate celelalte sunt respinse la proxy sau în Web Application Firewall.
Importantă este încadrarea. Propunerea nu provine de la php.net, ci de la autori de specialitate și este gândită explicit ca măsură temporară. php.net indică propriile măsuri provizorii, adunate la Măsuri imediate dacă nu puteți încă aplica patchul. Filtrul le poate completa, nu le poate înlocui.
Descriem aici cum îl introduceți controlat. Detalii despre motivul pentru care ar putea ajuta împotriva căror atacuri le lăsăm deliberat deoparte.
Ce face filtrul și unde dăunează
Ideea din spate este o micșorare a suprafeței de atac. Majoritatea paginilor unui site nu au nevoie de încărcări de fișiere. Dacă doar câteva căi cunoscute mai acceptă astfel de cereri, o mare parte din posibilele încercări de atac nu mai ajung deloc la PHP.
Reversul este la fel de clar. Orice funcție care trimite cereri multipart și lipsește de pe lista de excepții cade. Asta nu privește doar formularele evidente de upload.
| Funcție | Folosește adesea multipart/form-data | Riscul la blocare |
|---|---|---|
| Formulare de contact și de candidatură cu atașament | da | cererile se pierd |
| Gestionarea media din backend-ul CMS | da | redacția nu poate încărca imagini |
| Import de produse sau clienți | da | interfețele se strică pe tăcute |
| Formulare fără atașament | uneori | în funcție de constructorul de formulare |
| Interfețe și răspunsuri ale unor servicii externe | rar, dar posibil | căderea este observată târziu |
Se adaugă o problemă de principiu: Cloudflare, care a lansat el însuși reguli de protecție împotriva PHP2Shell, avertizează că regulile bazate doar pe datele cererii nu sunt suficiente. Cum gândiți împreună cele două niveluri descrie WAF sau actualizare: de ce aveți nevoie de ambele.
Pasul 1: mai întâi jurnalizați, apoi blocați
Înainte să blocați ceva, aflați ce căi primesc, de fapt, cereri multipart. Jurnalele standard nu arată tipul de conținut. Pentru Nginx creați de aceea provizoriu un jurnal propriu:
# în blocul 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';
# în blocul server
# Atenție: un access_log în blocul server înlocuiește jurnalul moștenit,
# de aceea indicați aici din nou jurnalul normal.
access_log /var/log/nginx/access.log combined;
access_log /var/log/nginx/multipart-test.log multipart if=$multipart_fremd;
Intrările din $upload_pfad sunt exemple. Porniți cu o listă goală de excepții, atunci jurnalul de test arată toate POST-urile multipart. Sub Apache se poate face același lucru cu o variabilă de mediu:
# în VirtualHost
SetEnvIfNoCase Content-Type "^multipart/form-data" ist_multipart
CustomLog ${APACHE_LOG_DIR}/multipart-test.log combined env=ist_multipart
Lăsați jurnalul să ruleze câteva zile, ideal într-o perioadă în care au fost active și redacția, candidații și interfețele.
Pasul 2: stabiliți excepțiile și blocați controlat
Din jurnalul de test deduceți căile care au legitim nevoie de upload-uri. Comparați lista cu responsabilii: cine întreține conținutul, ce formulare există, ce servicii trimit date?
- Întocmiți lista de excepții din jurnal și din întrebări și introduceți-o în
$upload_pfadrespectiv în rândurileRewriteCond. - Activați filtrul mai întâi într-un mediu de test sau într-o fereastră de timp liniștită.
- Parcurgeți dumneavoastră înșivă toate formularele, încărcările și căile de comandă.
- Urmăriți jurnalul de erori pentru cereri respinse (starea 403) și completați lista la nevoie.
- Stabiliți o dată de încheiere: după actualizarea PHP și repornirea tuturor workerilor, filtrul este eliminat din nou.
În Nginx completați pentru aceasta, în blocul server, blocarea:
# în blocul server, după evaluarea fazei de jurnalizare
if ($multipart_fremd) {
return 403;
}
În Apache, sarcina o preia mod_rewrite. Potrivit documentației Apache, mai multe condiții sunt legate prin ȘI:
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]
Dacă folosiți un CDN sau un WAF în cloud, aceeași logică poate fi adesea reprodusă ca regulă proprie. Și acolo se aplică: mai întâi în modul de jurnalizare, apoi blocare.
Filtrul nu este un înlocuitor pentru actualizarea PHP și nici un motiv de a o amâna. PHP2Shell este remediată doar cu PHP 8.5.12, 8.4.27, 8.3.36, 8.2.35 sau cu un backport confirmat, urmat de repornirea tuturor proceselor PHP.
Încadrarea corectă a măsurii
Filtrul de upload face parte din seria altor propuneri care circulă în prezent. Unele sunt rezonabile, altele dăunătoare. O prezentare a sfaturilor pe care autorii de specialitate le resping, de exemplu blocarea tuturor cererilor cu cookie de sesiune, oferă Sfaturi greșite periculoase despre PHP2Shell.
Cum procesează PHP intern încărcările și de ce formatul multipart/form-data joacă aici un rol special explică Cum procesează PHP încărcările de fișiere. Pentru majoritatea firmelor, cel mai important pas nu este însă filtrul, ci un termen clar pentru actualizare.
Concluzie: o unealtă pentru zile, nu pentru luni
Filtrul de upload la margine este un exemplu tipic de măsură de urgență: poate micșora suprafața de atac în perioada de tranziție, dar are efecte secundare și nu are sprijin oficial din partea php.net. Folosit corect, cu fază de jurnalizare, listă de excepții coordonată, teste și dată de încheiere fixă, este justificabil. Fără acești pași riscați candidaturi pierdute, redacții blocate și erori tăcute ale interfețelor.
Luați de aceea decizia în mod conștient și consemnați cine a luat-o și când. Și păstrați ordinea în minte: mai întâi vine actualizarea PHP cu repornirea tuturor workerilor, măsurile provizorii de la php.net acoperă timpul până atunci, iar filtrul este cel mult un strat suplimentar.
Cum ajută PHP SOS concret?
- Evaluarea situației: Clarificăm dacă un filtru de upload are sens în situația dumneavoastră sau dacă actualizarea este posibilă mai repede.
- Jurnalizare și evaluare: Configurăm faza de jurnalizare și deducem lista de excepții din accesări reale.
- Blocare controlată: Activăm filtrul, testăm formularele și căile de comandă și supraveghem cererile respinse.
- Demontare curată: În cadrul WAF și patching virtual eliminăm din nou filtrul după actualizare.
Întrebări frecvente
Este filtrarea cererilor multipart o recomandare oficială de la php.net?
Nu. php.net indică alte măsuri provizorii, de exemplu limite pentru post_max_size și dezactivarea session.upload_progress. Filtrarea la margine este o propunere din articole de specialitate și este gândită explicit doar ca măsură temporară.
Ce funcții pot cădea din cauza filtrului?
Tot ce trimite fișiere sau formulare în format multipart și nu se află pe lista dumneavoastră de excepții: formulare de contact cu atașament, formulare de candidatură, gestionarea media din CMS, funcții de import, unele interfețe și răspunsuri de plată. De aceea, înainte de blocare vine o fază de jurnalizare.
Înlocuiește filtrul actualizarea PHP?
Nu. El reduce cel mult suprafața de atac în perioada de tranziție. Cloudflare atrage el însuși atenția că regulile bazate doar pe datele cererii nu sunt suficiente. PHP2Shell este remediată doar cu o versiune PHP patchuită și repornirea tuturor workerilor.
Ar trebui în schimb să blochez cererile cu PHPSESSID?
Nu. Acest sfat care circulă este respins explicit de autorii de specialitate. El paralizează autentificările și coșurile de cumpărături, fără a oferi o protecție de încredere.