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 →

Správné nastavení memory_limit

memory_limit omezuje paměť na jeden požadavek PHP. Po PHP2Shell php.net přechodně radí opak. Co platí v běžném provozu, v přechodné době a po aktualizaci.

Stav 5 min čteníHardening a konfigurace

Stručně: memory_limit určuje, kolik paměti smí zabrat jeden požadavek PHP; výchozí hodnota je 128M. V běžném provozu nastavte konečnou hodnotu odpovídající aplikaci a uzamkněte ji pomocí php_admin_value. Dokud PHP2Shell není zaplatováno, php.net přechodně radí memory_limit=-1, bez možnosti přepsání a v kombinaci s limitem přes kontejner nebo cgroup, ne přes RLIMIT_AS nebo RLIMIT_DATA. Po aktualizaci platí opět konečná hodnota.

Rutinní nastavení, které je náhle bezpečnostním tématem

Léta byl memory_limit ladicím šroubem pro vývojáře. Když web hlásí „Allowed memory size exhausted“, hodnota se zvýší a problém je vyřešen. S PHP2Shell se z toho stala bezpečnostní otázka a doporučení php.net působí na první pohled paradoxně: pro přechodnou dobu má paměťový limit PHP zcela odpadnout.

Pozadím je CVE-2026-109618. Podle projektu PHP může stav Out-of-Memory přerušit PHP ve chvíli, kdy jsou data požadavku inicializována jen částečně. Úklid požadavku pak může neplatná data považovat za platná. Technické podrobnosti jsou na stránce CVE-2026-109618, co se při nedostatku paměti děje uvnitř PHP, vysvětluje memory_limit a Out-of-Memory. Pro provozovatele je důležitá otázka: Která hodnota platí kdy a kde musí být zapsána?

Co memory_limit dělá v běžném provozu

Podle příručky PHP omezuje memory_limit paměť, kterou smí skript zabrat, a chrání tak server před špatně napsaným kódem. Výchozí hodnota je 128M, -1 znamená bez limitu. Zkrácené zápisy jako 256M nebo 1G jsou povoleny.

Pro bezpečnost jsou důležité dvě vlastnosti. Za prvé lze hodnotu změnit kdekoli, i za běhu pomocí ini_set(). Mnoho CMS a e-shopů ji samo zvyšuje, například pro importy nebo zpracování obrázků. Kdo chce hodnotu vynutit, musí ji nastavit pomocí php_admin_value; podle příručky takto nastavené hodnoty nelze přepsat pomocí ini_set(). Za druhé příručka doporučuje, aby memory_limit byl větší než post_max_size.

Jaká hodnota se hodí, závisí na aplikaci. Pohled do chybového logu ukáže, zda se vyskytují hlášení o vyčerpané paměti a při kterých voláních. Osvědčilo se nastavit hodnotu pro každý web v jeho vlastním poolu FPM: velkorysejší pro e-shop s importy, skromnější pro jednoduchou firemní stránku. Plošně velmi vysoká hodnota pro všechny weby maří ochranný účinek, protože jediný chybný nebo zneužitý požadavek pak může zabrat hodně paměti.

Od PHP 8.5 existuje navíc max_memory_limit. Toto nastavení lze zadat jen při startu a omezuje, jak vysoko lze memory_limit vůbec nastavit. Vyšší hodnoty se s varováním oříznou. Výchozí -1 znamená žádný horní limit.

memory_limit po PHP2Shell: přechodné opatření od php.net

Pro servery, které ještě nejsou aktualizovány na 8.5.12, 8.4.27, 8.3.36 nebo 8.2.35, případně na potvrzený backport, uvádí php.net v bezpečnostním oznámení z 21. 10. 2026 následující kroky. Snižují riziko jednotlivých cest útoku, instalaci podle php.net ale nečiní bezpečnou:

  1. Nastavit memory_limit=-1, pokud možno tak, aby aplikace hodnotu nemohly přepsat, například pomocí php_admin_value v poolu FPM nebo v konfiguraci Apache.
  2. Ověřit, že se nikde znovu nenastavuje konečný limit, ani v jiném poolu, ani v konfiguraci adresáře, ani v aplikaci.
  3. Nastavit limit paměti přes kontejner nebo cgroup, jako ochranu dostupnosti, pokud možno tak, aby se při překročení ukončil jen dotčený worker.
  4. Nepoužívat RLIMIT_AS ani RLIMIT_DATA. Tyto limity mohou podle php.net vyvolat právě tu zranitelnou chybu při požadavku na paměť.

php.net k tomu vysvětluje, že -1 odstraní cíleně vyvolatelné dosažení paměťového limitu PHP, chyba paměti na nižší úrovni však může zranitelnou cestu stále dosáhnout. Přehled všech přechodných opatření je na stránce Okamžitá opatření, když zatím nemůžete záplatovat.

; Pool FPM, např. /etc/php/8.3/fpm/pool.d/www.conf (jen do aktualizace)
php_admin_value[memory_limit] = -1
# Kde všude se memory_limit nastavuje (jen čtení)
grep -rn 'memory_limit' /etc/php/ /etc/apache2/ 2>/dev/null
grep -rn --include='*.php' -E "ini_set\s*\(\s*['\"]memory_limit" /var/www | head -20
grep -rn --include='.user.ini' 'memory_limit' /var/www

Jak nastavit limit cgroup pro službu FPM, popisuje Nastavení limitů paměti pomocí systemd a cgroups. Bez tohoto vnějšího limitu může jediný požadavek přivést celý server do nedostatku paměti.

Důležité

Po každé změně restartujte všechny workery PHP. Běžící worker si ponechává své staré hodnoty.

Co platí po aktualizaci

S opravenými verzemi se podle příručky PHP změnilo i chování memory_limit. Od 8.5.12, 8.4.27, 8.3.36 a 8.2.35 jde o měkký limit: požadavek na paměť, který jej překročí, smí být ve většině případů ještě dokončen, než se vyvolá chyba. Nové nastavení memory_hard_limit_percent určuje tvrdý limit, který se nikdy nepřekročí.

Nastavení Hodnota Účinek podle příručky
memory_hard_limit_percent nenastaveno nebo -1 výchozí tvrdý limit dvojnásobek memory_limit do 1G, nad tím memory_limit plus 1G
memory_hard_limit_percent = 150 příklad při memory_limit=128M tvrdý limit 192M
memory_limit = -1 bez limitu pak není ani tvrdý limit

Příručka uvádí praktický kontrolní bod: pokud není memory_hard_limit_percent rozpoznáno, používaná verze PHP je postižena a je nutné ji aktualizovat. U backportů distribucí zkontrolujte stav navíc podle changelogu balíčku.

# Zná binárka FPM nové nastavení? (upravte číslo verze)
php-fpm8.3 -i | grep -E 'memory_hard_limit_percent|memory_limit'

Po aktualizaci splnilo memory_limit=-1 svůj účel. Vraťte se ke konečné hodnotě odpovídající aplikaci a uzamkněte ji pomocí php_admin_value. Limit cgroup může zůstat jako další ochranná vrstva.

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

  • Zjistíme, kde se na vašem serveru memory_limit nastavuje a přepisuje, včetně aplikací.
  • Přechodná opatření od php.net zavedeme na správném místě a doplníme limit cgroup pro službu FPM.
  • Prostřednictvím služby záplatování PHP dostaneme PHP na opravený stav a restartujeme všechny workery.
  • Poté znovu nastavíme vhodnou konečnou hodnotu a nastavení zdokumentujeme.

Časté dotazy

Jaká je výchozí hodnota memory_limit?

Podle příručky PHP 128M. Hodnota omezuje, kolik paměti smí zabrat jeden skript. Lze ji změnit v php.ini, v konfiguraci serveru, v poolu FPM i za běhu pomocí ini_set(), pokud není uzamčena přes php_admin_value.

Proč php.net u PHP2Shell radí memory_limit=-1?

Jedna ze zranitelností, CVE-2026-109618, souvisí se stavem při nedostatku paměti. Podle php.net memory_limit=-1 odstraní cíleně vyvolatelné dosažení paměťového limitu PHP, nikoli však každou paměťovou chybu. Opatření není úplnou ochranou a musí se kombinovat s limitem paměti přes kontejner nebo cgroup.

Smím limit místo toho nastavit přes ulimit?

Ne. php.net výslovně nedoporučuje používat RLIMIT_AS nebo RLIMIT_DATA jako náhradu, protože tyto limity mohou vyvolat právě tu zranitelnou chybu při požadavku na paměť. Doporučen je limit přes kontejner nebo cgroup.

Co platí po aktualizaci na opravenou verzi PHP?

Podle příručky je memory_limit v opravených verzích měkký limit, doplněný tvrdým limitem přes memory_hard_limit_percent. Přechodné opatření s -1 pak splnilo svůj účel a měla by znovu platit konečná hodnota odpovídající aplikaci.

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