Aktuální situace: PHP2Shell. Dvě kritické zranitelnosti PHP (CVSS 9.2) umožňují spustit škodlivý kód bez přihlášení. Záplaty od 21. 10. 2026.Co nyní udělat →

Rozumné omezení post_max_size a upload_max_filesize

Limity nahrávání působí na třech místech: ve webovém serveru, v PHP a v aplikaci. Jak hodnoty nastavit shodně, i s přechodnými hodnotami od php.net k PHP2Shell.

Stav 4 min čteníHardening a konfigurace

Stručně: post_max_size omezuje celkovou velikost požadavku POST, upload_max_filesize jednotlivý soubor; výchozí hodnoty jsou podle příručky PHP 8M a 2M. Hodnoty musí odpovídat limitům ve webovém serveru a v aplikaci, jinak nahrávání selže bez jasného hlášení. Do aktualizace kvůli PHP2Shell php.net radí post_max_size = 8M bez nahrávání nebo 32M s nahráváním, upload_max_filesize pod tím, nastavené tak, aby je aplikace nemohly přepsat.

Když formulář pro uchazeče náhle mlčí

Po přechodných opatřeních k PHP2Shell snížilo mnoho správců post_max_size. O pár dní později hlásí personální oddělení, že přihlášky nedorazí. Formulář se prostě znovu načte, žádné chybové hlášení není. Důvod: požadavek se třemi přílohami PDF byl větší než nový limit a PHP data formuláře zahodilo.

Příklad ukazuje základní problém. Limity nahrávání působí na několika místech současně a každé místo reaguje při překročení jinak. Kdo řetězec zná, může hodnoty nastavit tak, aby chránily, aniž by rušily provoz. Jak PHP nahrávání interně zpracovává, vysvětluje Jak PHP zpracovává nahrávání souborů; bezpečné programování funkcí nahrávání popisuje Bezpečné nahrávání souborů v PHP.

Řetězec limitů nahrávání

Požadavek prochází několika limity, než jej aplikace uvidí. Následující údaje pocházejí z dokumentací Nginx, Apache a PHP:

Místo Nastavení Výchozí hodnota podle dokumentace Při překročení
Nginx client_max_body_size 1m chyba 413 pro prohlížeč
Apache od 2.4.54 LimitRequestBody 1 GiB (do 2.4.53: neomezeno) chybová odpověď místo zpracování
PHP post_max_size 8M $_POST a $_FILES prázdné
PHP upload_max_filesize 2M soubor je odmítnut s chybovým kódem
PHP max_file_uploads 20 další soubory se ignorují
PHP max_input_vars 1000 další pole formuláře chybí

Z toho plyne jednoduché pravidlo: upload_max_filesize menší než post_max_size, post_max_size menší než limit ve webovém serveru. Příručka PHP navíc doporučuje, aby memory_limit byl obecně větší než post_max_size. Během přechodného opatření k PHP2Shell s memory_limit=-1 tuto roli přebírá limit přes kontejner nebo cgroup; více v článku Správné nastavení memory_limit.

post_max_size po PHP2Shell: co radí php.net

V bezpečnostním oznámení z 21. 10. 2026 uvádí php.net pro servery bez aktualizace nízké limity požadavků jako jedno z přechodných opatření. Snižují riziko jednotlivých cest útoku, ale výslovně nejsou úplnou ochranou:

  1. Bez nahrávání souborů: post_max_size = 8M.
  2. S nahráváním souborů: post_max_size = 32M.
  3. V obou případech: držet upload_max_filesize pod post_max_size.
  4. Navíc zvážit: limity ve webovém serveru nebo proxy pro dekódovanou velikost požadavku, počet vstupních polí, počet částí multipart, počet řádků hlavičky a hloubku vnoření. Podle php.net musí tyto limity zachytit i požadavky bez použitelného údaje Content-Length.

Hodnoty patří tam, kde je aplikace nemohou přepsat. Protože lze post_max_size a upload_max_filesize podle příručky měnit na úrovni adresáře, mohl by je .user.ini nebo u mod_php .htaccess jinak znovu zvýšit:

; Pool FPM webu, s nahráváním (přechodně do aktualizace)
php_admin_value[post_max_size] = 32M
php_admin_value[upload_max_filesize] = 24M
php_admin_value[max_file_uploads] = 5

Ve webovém serveru nastavte limit těsně nad touto hodnotou, aby příliš velké požadavky k PHP vůbec nedorazily:

# Nginx, v bloku server nebo location
client_max_body_size 32m;
# Apache, ve VirtualHost: 32 MiB v bajtech
LimitRequestBody 33554432

Poté znovu načtěte všechny workery PHP a webový server. Přehled všech přechodných opatření je na stránce Okamžitá opatření, když zatím nemůžete záplatovat. Zda a jak lze požadavky na nahrávání navíc filtrovat na proxy, osvětluje Filtrování požadavků na nahrávání na okraji sítě.

Důležité

Po každé změně otestujte formuláře s největšími legitimními požadavky: přihlášky s několika přílohami, importy produktů, galerie obrázků. Příliš těsná hodnota ochromí obchodní procesy, aniž by někdo viděl chybové hlášení.

Zjistit správnou hodnotu pro váš web

Místo plošných hodnot se vyplatí krátká inventura. Vypište všechny formuláře s nahráváním a zapište největší legitimní soubor a nejvyšší počet souborů současně. Z toho vyplyne potřeba: upload_max_filesize pokrývá největší jednotlivý soubor, post_max_size součet všech souborů jednoho požadavku plus malou rezervu pro pole formuláře.

Pokud je potřeba nad 32M, neodpovídá přechodnému doporučení php.net. To je další důvod, proč aktualizaci upřednostnit. Velká nahrávání lze vyřizovat také přes vlastní subdoménu s vlastním poolem, aby zbytek webu zachoval úzké limity.

Po aktualizaci na 8.5.12, 8.4.27, 8.3.36, 8.2.35 nebo potvrzený backport můžete hodnoty opět přizpůsobit skutečné potřebě. Velkorysejší, než je nutné, by přesto být neměly: každý limit nad rámec potřeby zvětšuje plochu pro útok bez užitku. Pokud web nahrávání vůbec nepotřebuje, je nejčistším řešením file_uploads = Off.

Správně číst příznaky chyb

Když nahrávání selhává, chování prozradí, který limit zabírá. Stránka s chybou 413 pochází od webového serveru. Formulář, který se bez hlášení znovu načte nebo ohlásí „neplatný požadavek“, ukazuje na prázdná data $_POST, tedy na post_max_size. Hlášení aplikace k jednotlivému souboru odpovídá upload_max_filesize. A chybějící pole ve velmi velkých formulářích, například u variant produktů, svědčí o max_input_vars. Chybový log PHP obsahuje při překročeném post_max_size zpravidla varování s velikostí požadavku.

Aby uživatelé nezůstali bezradní, měla by aplikace tento případ rozpoznat. Příručka PHP k tomu navrhuje jednoduchou cestu: formulář předá v adrese značku, například ?processed=1. Pokud tato značka dorazí, ale $_POST a $_FILES jsou prázdné, byl požadavek příliš velký a aplikace může zobrazit srozumitelné hlášení s povolenou velikostí.

Jak konkrétně pomáhá PHP SOS?

  • Zmapujeme všechny cesty nahrávání vašich webů a zjistíme skutečně potřebné velikosti.
  • Limity webového serveru, PHP a poolů nastavíme shodně a uzamčené proti přepsání, včetně přechodných hodnot od php.net.
  • Po přechodu otestujeme formuláře, importy a nahrávání a hodnoty cíleně upravíme.
  • V rámci zpevnění serveru po aktualizaci hodnoty vrátíme na trvalou potřebu.

Časté dotazy

Jaký je rozdíl mezi post_max_size a upload_max_filesize?

upload_max_filesize omezuje velikost jednotlivého nahraného souboru. post_max_size omezuje celková data požadavku POST, tedy všechny soubory a pole formuláře dohromady. Podle příručky PHP proto musí být post_max_size větší než upload_max_filesize.

Co se stane, když je požadavek větší než post_max_size?

Podle příručky PHP jsou pak $_POST a $_FILES prázdné. Aplikace tedy nedostane vůbec žádná data formuláře a často zobrazí jen nejasné chybové hlášení nebo formulář znovu načte. Proto se tato chyba špatně rozpoznává.

Jaké hodnoty doporučuje php.net kvůli PHP2Shell?

Jako přechodné opatření do aktualizace: post_max_size = 8M pro aplikace bez nahrávání souborů, 32M pro aplikace s nahráváním a upload_max_filesize pod touto hodnotou. Podle php.net to není úplná ochrana; zranitelnosti uzavře jen aktualizace na opravenou verzi PHP.

Mohu post_max_size změnit v kódu pomocí ini_set()?

Ne. Podle příručky PHP lze post_max_size měnit jen na úrovni adresáře, například v php.ini, v poolu FPM, v .user.ini nebo u mod_php v .htaccess. Kdo chce hodnotu vynutit, nastaví ji pomocí php_admin_value, pak ji nemůže přepsat ani .user.ini.

Zdroje

Okamžitý kontakt

Každá hodina se počítá. Napište nám hned.

Stručně popište systém, verzi PHP a pozorování. Ozveme se, vyjasníme situaci a budeme pracovat na dálku, dokud nebude incident uzavřen a zdokumentován.

Okamžitá pomoc