Текуща ситуация: PHP2Shell. Две критични уязвимости в PHP (CVSS 9,2) позволяват злонамерен код без вход. Корекции от 21.10.2026 г.Какво да направите сега →

Правилна настройка на memory_limit

memory_limit ограничава паметта за всяка PHP заявка. След PHP2Shell php.net временно съветва обратното. Какво важи в нормална работа, по време на прехода и след актуализацията.

Актуалност 5 мин. четенеЗаздравяване и конфигурация

Накратко: memory_limit определя колко памет може да заема една отделна PHP заявка; стойността по подразбиране е 128M. В нормална работа задавате краен размер, който подхожда на приложението, и го заключвате с php_admin_value. Докато PHP2Shell не е коригиран с пач, php.net временно съветва memory_limit=-1, което не може да се презаписва и е комбинирано с лимит чрез контейнер или cgroup, не чрез RLIMIT_AS или RLIMIT_DATA. След актуализацията отново важи краен размер.

Рутинна настройка, която изведнъж е тема за сигурност

С години memory_limit беше регулатор за разработчиците. Ако един сайт съобщи „Allowed memory size exhausted", стойността се увеличава и проблемът е решен. С PHP2Shell това се превърна във въпрос на сигурност, а препоръката на php.net на пръв поглед изглежда парадоксална: за прехода собственият лимит на паметта на PHP трябва да отпадне изцяло.

Причината е CVE-2026-109618. Според проекта PHP състояние с недостиг на памет (Out-of-Memory) може да прекъсне PHP, докато данните на заявката са само частично инициализирани. Почистването на заявката може тогава да третира невалидни данни като валидни. Техническите подробности са в CVE-2026-109618, а какво се случва вътре в PHP при недостиг на памет, обяснява memory_limit и Out-of-Memory. За операторите важи въпросът: коя стойност кога важи и къде трябва да стои?

Какво дава memory_limit в нормална работа

Според ръководството на PHP memory_limit ограничава паметта, която един скрипт може да заема, и така защитава сървъра от зле написан код. Стойността по подразбиране е 128M, а -1 означава без лимит. Съкратени записи като 256M или 1G са позволени.

Две свойства са важни за сигурността. Първо, стойността може да се променя навсякъде, и по време на изпълнение чрез ini_set(). Много CMS и магазини сами я увеличават, например за импорти или обработка на изображения. Който иска да наложи стойност, трябва да я зададе с php_admin_value; според ръководството така зададени стойности не могат да се презаписват с ini_set(). Второ, ръководството препоръчва memory_limit да е по-голям от post_max_size.

Коя стойност подхожда, зависи от приложението. Погледът в лога за грешки показва дали се появяват съобщения за изчерпана памет и при кои извиквания. Доказало се е стойността да се задава за всеки сайт в собствения му FPM пул: по-щедра за магазин с импорти, по-пестелива за обикновена фирмена страница. Общо много висока стойност за всички сайтове пропилява защитния ефект, защото тогава една-единствена погрешна или злоупотребена заявка може да свърже много памет.

От PHP 8.5 има допълнително max_memory_limit. Тази настройка може да се задава само при стартиране и ограничава докъде изобщо може да се задава memory_limit. По-високите стойности се орязват с предупреждение. Стойността по подразбиране -1 означава без горна граница.

memory_limit след PHP2Shell: преходната мярка на php.net

За сървъри, които още не са актуализирани до 8.5.12, 8.4.27, 8.3.36 или 8.2.35 или до потвърден backport, php.net в съобщението за сигурност от 21.10.2026 г. посочва следните стъпки. Те намаляват риска на отделни пътища за атака, но според php.net не правят една инсталация сигурна:

  1. Задайте memory_limit=-1, по възможност така, че приложенията да не могат да презапишат стойността, например с php_admin_value в пула на FPM или в конфигурацията на Apache.
  2. Проверете дали никъде не се задава отново краен лимит, нито в друг пул, нито в директорийна конфигурация, нито в приложението.
  3. Задайте лимит на паметта чрез контейнер или cgroup, като защита на наличността, по възможност така, че при надвишаване да се прекратява само засегнатият worker процес.
  4. Не използвайте RLIMIT_AS или RLIMIT_DATA. Според php.net тези лимити могат да предизвикат точно уязвимата грешка при заявка за памет.

php.net обяснява, че -1 премахва целенасочено предизвикваното достигане на границата на паметта на PHP, но грешка с паметта на по-ниско ниво все още може да достигне уязвимия път. Прегледът на всички преходни мерки е в Незабавни мерки, когато още не можете да пачнете.

; Пул на FPM, напр. /etc/php/8.3/fpm/pool.d/www.conf (само до актуализацията)
php_admin_value[memory_limit] = -1
# Къде навсякъде се задава memory_limit (само четене)
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

Как да зададете лимита на cgroup за услугата FPM, описва Задаване на лимити на паметта със systemd и cgroups. Без този външен лимит една отделна заявка може да докара целия сървър до недостиг на памет.

Важно

След всяка промяна рестартирайте всички PHP worker процеси. Работещият worker запазва старите си стойности.

Какво важи след актуализацията

С коригираните версии според ръководството на PHP се е променило и поведението на memory_limit. От 8.5.12, 8.4.27, 8.3.36 и 8.2.35 той е мек лимит: заявка за памет, която го надвишава, в повечето случаи още може да бъде завършена, преди да се предизвика грешката. Нова настройка, memory_hard_limit_percent, определя твърд лимит, който никога не се надвишава.

Настройка Стойност Ефект според ръководството
memory_hard_limit_percent не е зададен или -1 по подразбиране твърд лимит двойно по-висок от memory_limit до 1G, над това memory_limit плюс 1G
memory_hard_limit_percent = 150 пример при memory_limit=128M твърд лимит 192M
memory_limit = -1 без лимит тогава няма и твърд лимит

Ръководството посочва практическа точка за проверка: ако memory_hard_limit_percent не се разпознава, използваната версия на PHP е засегната и трябва да се актуализира. При backport корекции на дистрибуциите проверете допълнително състоянието през changelog на пакета.

# Познава ли двоичният файл на FPM новата настройка? (коригирайте номера на версията)
php-fpm8.3 -i | grep -E 'memory_hard_limit_percent|memory_limit'

След актуализацията memory_limit=-1 е изпълнил целта си. Върнете се към крайна стойност, която подхожда на приложението, и я заключете с php_admin_value. Лимитът на cgroup може да остане като допълнителен защитен слой.

Как помага PHP SOS конкретно?

  • Установяваме къде на Вашия сървър се задава и презаписва memory_limit, включително от приложенията.
  • Прилагаме преходните мерки на php.net на правилното място и добавяме лимит на cgroup за услугата FPM.
  • Чрез PHP пач услугата довеждаме PHP до коригирано състояние и рестартираме всички worker процеси.
  • След това отново задаваме подходяща крайна стойност и документираме настройките.

Често задавани въпроси

Каква е стойността по подразбиране на memory_limit?

Според ръководството на PHP 128M. Стойността ограничава колко памет може да заема един отделен скрипт. Тя може да се променя в php.ini, в конфигурацията на сървъра, в пула на FPM и по време на изпълнение чрез ini_set(), стига да не е заключена с php_admin_value.

Защо php.net съветва memory_limit=-1 при PHP2Shell?

Една от уязвимостите, CVE-2026-109618, е свързана със състоянието при недостиг на памет. Според php.net memory_limit=-1 премахва целенасочено предизвикваното достигане на границата на паметта на PHP, но не всяка грешка с паметта. Мярката не е пълна защита и трябва да се комбинира с лимит на паметта чрез контейнер или cgroup.

Мога ли вместо това да задам лимита с ulimit?

Не. php.net изрично съветва да не се използват RLIMIT_AS или RLIMIT_DATA като заместител, защото тези лимити могат да предизвикат точно уязвимата грешка при заявка за памет. Препоръчва се лимит чрез контейнер или cgroup.

Какво важи след актуализацията до коригирана версия на PHP?

Според ръководството в коригираните версии memory_limit е мек лимит, допълнен от твърд лимит чрез memory_hard_limit_percent. Преходната мярка със стойност -1 тогава е изпълнила целта си и трябва да важи отново краен, подходящ за приложението стойност.

Източници

Незабавен контакт

Всеки час има значение. Пишете ни сега.

Опишете накратко системата, версията на PHP и какво сте забелязали. Ние се свързваме с Вас, уточняваме ситуацията и работим отдалечено, докато инцидентът бъде приключен и документиран.

Незабавна помощ