Stručne: Filtrovať požiadavky uploadu na okraji znamená odmietať požiadavky POST typu multipart/form-data na proxy, webovom serveri alebo vo WAF, ak nesmerujú na známu cestu uploadu. Odborní autori to navrhujú ako dočasné, neoficiálne opatrenie proti PHP2Shell. Môže pokaziť formuláre a uploady a nikdy nenahrádza aktualizáciu. Postupujte v troch krokoch: zapisovať do protokolu, určiť výnimky, až potom blokovať, s pevným dátumom konca.
Návrh z odbornej diskusie
Kým nie je server zaplátaný, prevádzkovatelia hľadajú všetko, čo znižuje riziko. V odbornej diskusii o PHP2Shell sa objavil návrh: požiadavky POST vo formáte multipart/form-data, teda vo formáte pre uploady súborov a niektoré formuláre, povoliť už len tam, kde ich aplikácia skutočne očakáva. Všetky ostatné sa odmietnu na proxy alebo vo Web Application Firewall.
Dôležité je zaradenie. Návrh nepochádza od php.net, ale od odborných autorov a je výslovne myslený ako dočasné opatrenie. php.net uvádza vlastné prechodné opatrenia, zhromaždené pri Okamžité opatrenia, ak ešte nemôžete záplatovať. Filter ich môže dopĺňať, nie nahradiť.
Tu opisujeme, ako ho zaviesť kontrolovane. Podrobnosti o tom, prečo by mohol pomôcť proti ktorým útokom, zámerne vynechávame.
Čo filter prináša a kde škodí
Myšlienkou je zmenšenie útočnej plochy. Väčšina stránok webu nepotrebuje uploady súborov. Ak takéto požiadavky prijíma už len niekoľko známych ciest, veľká časť možných pokusov o útok sa k PHP vôbec nedostane.
Odvrátená strana je rovnako jasná. Každá funkcia, ktorá odosiela požiadavky multipart a chýba na zozname výnimiek, vypadne. Týka sa to nielen zjavných formulárov uploadu.
| Funkcia | Často používa multipart/form-data | Riziko pri blokovaní |
|---|---|---|
| Kontaktné formuláre a formuláre žiadostí o zamestnanie s prílohou | áno | požiadavky sa strácajú |
| Správa médií v backende CMS | áno | redakcia nemôže nahrávať obrázky |
| Import produktov alebo zákazníkov | áno | rozhrania sa potichu pokazia |
| Formuláre bez prílohy | niekedy | podľa stavebnice formulárov |
| Rozhrania a spätné hlásenia externých služieb | zriedka, ale možné | výpadok sa zistí neskoro |
K tomu pribúda zásadný problém: Cloudflare, ktorý sám nasadil ochranné pravidlá proti PHP2Shell, upozorňuje, že pravidlá len na základe údajov požiadavky nestačia. Ako obe úrovne pochopiť spolu, opisuje WAF alebo aktualizácia: prečo potrebujete oboje.
Krok 1: najprv zapisovať do protokolu, potom blokovať
Skôr než niečo zablokujete, zistite, ktoré cesty vôbec dostávajú požiadavky multipart. Štandardné protokoly typ obsahu neukazujú. Pre Nginx preto dočasne zriaďte vlastný protokol:
# v bloku 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';
# v bloku server
# Pozor: access_log v bloku server nahrádza zdedený protokol,
# preto tu uveďte bežný protokol znova.
access_log /var/log/nginx/access.log combined;
access_log /var/log/nginx/multipart-test.log multipart if=$multipart_fremd;
Záznamy v $upload_pfad sú príklady. Začnite s prázdnym zoznamom výnimiek, potom testovací protokol ukáže všetky POST multipart. Pod Apache sa to isté dosiahne pomocou premennej prostredia:
# vo VirtualHost
SetEnvIfNoCase Content-Type "^multipart/form-data" ist_multipart
CustomLog ${APACHE_LOG_DIR}/multipart-test.log combined env=ist_multipart
Nechajte protokol bežať niekoľko dní, ideálne počas obdobia, keď boli aktívne aj redakcia, uchádzači a rozhrania.
Krok 2: určiť výnimky a blokovať kontrolovane
Z testovacieho protokolu odvodíte cesty, ktoré uploady legitímne potrebujú. Zoznam konzultujte so zodpovednými: kto spravuje obsah, aké formuláre existujú, ktoré služby posielajú údaje?
- Zostaviť zoznam výnimiek z protokolu a spätných otázok a zapísať ho do
$upload_pfadresp. do riadkovRewriteCond. - Filter najprv aktivovať v testovacom prostredí alebo v pokojnom časovom okne.
- Všetky formuláre, uploady a objednávkové cesty si sami prejsť.
- Chybový protokol sledovať na odmietnuté požiadavky (stav 403) a zoznam podľa potreby doplniť.
- Určiť dátum konca: po aktualizácii PHP a reštarte všetkých workerov sa filter opäť odstráni.
V Nginx na to doplníte v bloku server blokovanie:
# v bloku server, po vyhodnotení fázy protokolu
if ($multipart_fremd) {
return 403;
}
V Apache túto úlohu preberá mod_rewrite. Viaceré podmienky sa podľa dokumentácie Apache spájajú operátorom 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]
Ak používate CDN alebo cloudovú WAF, rovnakú logiku možno často zobraziť ako vlastné pravidlo. Aj tam platí: najprv v režime protokolu, potom blokovať.
Filter nie je náhradou za aktualizáciu PHP ani dôvodom ju odkladať. PHP2Shell je opravené len s PHP 8.5.12, 8.4.27, 8.3.36, 8.2.35 alebo potvrdeným backportom, nasledovaným reštartom všetkých procesov PHP.
Opatrenie správne zaradiť
Filter uploadu patrí do radu s ďalšími návrhmi, ktoré v súčasnosti kolujú. Niektoré sú zmysluplné, iné škodlivé. Prehľad, ktoré tipy odborní autori odmietajú, napríklad blokovanie všetkých požiadaviek so session cookie, podáva Nebezpečné nesprávne tipy k PHP2Shell.
Ako PHP interne spracúva uploady a prečo má formát multipart/form-data osobitnú úlohu, vysvetľuje Ako PHP spracúva nahrávanie súborov. Pre väčšinu firiem však nie je najdôležitejším krokom filter, ale jasný termín aktualizácie.
Záver: nástroj na dni, nie na mesiace
Filter uploadu na okraji je typickým príkladom núdzového opatrenia: môže v prechodnom období zmenšiť útočnú plochu, má však vedľajšie účinky a nemá oficiálnu podporu php.net. Pri správnom nasadení, s fázou protokolu, odsúhlaseným zoznamom výnimiek, testmi a pevným dátumom konca je obhájiteľný. Bez týchto krokov riskujete stratené žiadosti o zamestnanie, zablokované redakcie a tiché chyby rozhraní.
Rozhodnutie preto urobte vedome a zaznamenajte, kto ho kedy urobil. A majte na pamäti poradie: najprv prichádza aktualizácia PHP s reštartom všetkých workerov, prechodné opatrenia php.net preklenú čas do vtedy a filter je prinajlepšom dodatočná vrstva.
Ako konkrétne pomáha PHP SOS?
- Posúdiť situáciu: objasníme, či je filter uploadu vo vašej situácii vôbec zmysluplný, alebo či je aktualizácia možná rýchlejšie.
- Zapisovať do protokolu a vyhodnotiť: zriadime fázu protokolu a zoznam výnimiek odvodíme zo skutočných prístupov.
- Blokovať kontrolovane: filter aktivujeme, otestujeme formuláre a objednávkové cesty a sledujeme odmietnuté požiadavky.
- Čisto odstrániť: v rámci WAF a virtuálneho záplatovania filter po aktualizácii opäť odstránime.
Časté otázky
Je filtrovanie požiadaviek multipart oficiálnym odporúčaním php.net?
Nie. php.net uvádza iné prechodné opatrenia, napríklad hranice pre post_max_size a vypnutie session.upload_progress. Filtrovanie na okraji je návrh z odborných príspevkov a výslovne je myslené len ako dočasné opatrenie.
Ktoré funkcie môžu kvôli filtru vypadnúť?
Všetko, čo odosiela súbory alebo formuláre vo formáte multipart a nie je na vašom zozname výnimiek: kontaktné formuláre s prílohou, formuláre žiadostí o zamestnanie, správa médií v CMS, funkcie importu, niektoré rozhrania a platobné spätné hlásenia. Preto pred blokovaním prichádza fáza zapisovania do protokolu.
Nahrádza filter aktualizáciu PHP?
Nie. V prechodnom období najviac zmenšuje útočnú plochu. Cloudflare sám upozorňuje, že pravidlá len na základe údajov požiadavky nestačia. PHP2Shell je opravené len zaplátanou verziou PHP a reštartom všetkých workerov.
Mám namiesto toho blokovať požiadavky s PHPSESSID?
Nie. Odborní autori tento kolujúci tip výslovne odmietajú. Ochromí prihlásenia a nákupné košíky bez toho, aby poskytol spoľahlivú ochranu.