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

Разумно ограничаване на post_max_size и upload_max_filesize

Лимитите за качване действат на три места: в уеб сървъра, в PHP и в приложението. Така задавате стойностите съгласувано, включително с преходните стойности на php.net за PHP2Shell.

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

Накратко: post_max_size ограничава общия размер на една POST заявка, upload_max_filesize ограничава отделния файл; според ръководството на PHP стойностите по подразбиране са 8M и 2M. Стойностите трябва да отговарят на лимитите в уеб сървъра и в приложението, иначе качванията се провалят без ясно съобщение. До актуализацията за PHP2Shell php.net съветва post_max_size = 8M без качвания или 32M с качвания, upload_max_filesize под това, зададено така, че приложенията да не могат да го презапишат.

Когато формулярът за кандидатстване изведнъж замлъкне

След преходните мерки за PHP2Shell много администратори намалиха post_max_size. Няколко дни по-късно отделът за персонал съобщава, че кандидатурите не пристигат. Формулярът просто се презарежда, съобщение за грешка няма. Причината: заявката с три PDF прикачени файла е била по-голяма от новия лимит и PHP е отхвърлил данните на формуляра.

Примерът показва основния проблем. Лимитите за качване действат на няколко места едновременно и всяко място реагира различно, когато бъде надвишено. Който познава веригата, може да зададе стойностите така, че да защитават, без да пречат на работата. Как PHP обработва качванията вътрешно, обяснява Как PHP обработва качването на файлове; сигурното програмиране на функции за качване описва Сигурна реализация на качване на файлове в PHP.

Веригата от лимити за качване

Една заявка преминава през няколко лимита, преди приложението да я види. Следните данни идват от документациите на Nginx, Apache и PHP:

Място Настройка По подразбиране според документацията При надвишаване
Nginx client_max_body_size 1m грешка 413 към браузъра
Apache от 2.4.54 LimitRequestBody 1 GiB (до 2.4.53: неограничено) отговор с грешка вместо обработка
PHP post_max_size 8M $_POST и $_FILES са празни
PHP upload_max_filesize 2M файлът се отхвърля с код за грешка
PHP max_file_uploads 20 допълнителните файлове се игнорират
PHP max_input_vars 1000 допълнителните полета на формуляра липсват

От това следва просто правило: upload_max_filesize по-малък от post_max_size, post_max_size по-малък от лимита в уеб сървъра. Ръководството на PHP препоръчва освен това memory_limit като цяло да е по-голям от post_max_size. По време на преходната мярка за PHP2Shell с memory_limit=-1 тази роля поема лимитът чрез контейнер или cgroup; повече по темата в Правилна настройка на memory_limit.

post_max_size след PHP2Shell: какво съветва php.net

В съобщението за сигурност от 21.10.2026 г. php.net посочва за сървъри без актуализация ниски лимити на заявките като една от преходните мерки. Те намаляват риска на отделни пътища за атака, но изрично не са пълна защита:

  1. Без качване на файлове: post_max_size = 8M.
  2. С качване на файлове: post_max_size = 32M.
  3. И в двата случая: дръжте upload_max_filesize под post_max_size.
  4. Допълнително обмислете: лимити в уеб сървъра или прокси сървъра за декодирания размер на заявката, броя на входните полета, броя на частите multipart, броя на заглавните редове и дълбочината на влагане. Според php.net тези лимити трябва да обхващат и заявки без използваема стойност на Content-Length.

Стойностите принадлежат на място, където приложенията не могат да ги презапишат. Тъй като post_max_size и upload_max_filesize според ръководството могат да се променят на ниво директория, .user.ini или при mod_php .htaccess иначе биха могли да ги вдигнат отново:

; Пул на FPM на сайта, с качвания (преход до актуализацията)
php_admin_value[post_max_size] = 32M
php_admin_value[upload_max_filesize] = 24M
php_admin_value[max_file_uploads] = 5

В уеб сървъра поставяте лимита малко по-високо, за да не стигат прекомерно големите заявки до PHP изобщо:

# Nginx, в блок server или location
client_max_body_size 32m;
# Apache, във VirtualHost: 32 MiB в байтове
LimitRequestBody 33554432

След това презаредете всички PHP worker процеси и уеб сървъра. Прегледът на всички преходни мерки е в Незабавни мерки, когато още не можете да пачнете. Дали и как заявките за качване могат допълнително да се филтрират на прокси сървъра, разглежда Филтриране на заявки за качване в периферията.

Важно

След всяка промяна тествайте формулярите с най-големите легитимни заявки: кандидатури с няколко прикачени файла, импорти на продукти, галерии с изображения. Твърде тясна стойност спира бизнес процеси, без някой да види съобщение за грешка.

Определяне на правилната стойност за Вашия сайт

Вместо общи стойности си струва кратко проучване на наличното. Изброите всички формуляри с качвания и запишете най-големия легитимен файл и най-големия брой едновременни файлове. От това следва нуждата: upload_max_filesize покрива най-големия отделен файл, post_max_size сумата на всички файлове в една заявка плюс малък резерв за полетата на формуляра.

Ако нуждата е над 32M, тя не отговаря на преходната препоръка на php.net. Тогава това е още една причина да ускорите актуализацията. Големите качвания могат да се обработват и през отделен поддомейн със собствен пул, за да запази останалата част от сайта тесни лимити.

След актуализацията до 8.5.12, 8.4.27, 8.3.36, 8.2.35 или потвърден backport можете отново да съобразите стойностите с действителната нужда. По-щедри от необходимото все пак не бива да бъдат: всеки лимит, който надхвърля нуждата, увеличава повърхността за атака без полза. Ако даден сайт изобщо няма нужда от качвания, file_uploads = Off е най-чистото решение.

Правилно тълкуване на картините на грешките

Когато качванията се провалят, поведението издава кой лимит действа. Страница с грешка 413 идва от уеб сървъра. Формуляр, който се презарежда без съобщение или съобщава „невалидна заявка“, насочва към празни данни $_POST, тоест към post_max_size. Съобщение на приложението за един отделен файл подхожда на upload_max_filesize. А липсващи полета в много големи формуляри, например при варианти на продукти, говорят за max_input_vars. Логът за грешки на PHP по правило съдържа при надвишен post_max_size предупреждение с размера на заявката.

За да не остават потребителите безпомощни, приложението трябва да разпознава случая. Ръководството на PHP предлага за това прост начин: формулярът предава маркер в адреса, например ?processed=1. Ако маркерът пристигне, но $_POST и $_FILES са празни, заявката е била твърде голяма и приложението може да покаже разбираемо съобщение с допустимия размер.

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

  • Отчитаме всички пътища за качване на Вашите сайтове и установяваме действително необходимите размери.
  • Задаваме лимитите на уеб сървъра, PHP и пула съгласувано и заключени срещу презаписване, включително преходните стойности на php.net.
  • Тестваме формуляри, импорти и качвания след прехода и коригираме стойностите целенасочено.
  • В рамките на заздравяването на сървъра връщаме стойностите след актуализацията към трайната нужда.

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

Каква е разликата между post_max_size и upload_max_filesize?

upload_max_filesize ограничава размера на един отделен качен файл. post_max_size ограничава общите данни на една POST заявка, тоест всички файлове и полета на формуляра заедно. Според ръководството на PHP post_max_size затова трябва да е по-голям от upload_max_filesize.

Какво се случва, когато заявката е по-голяма от post_max_size?

Според ръководството на PHP тогава $_POST и $_FILES са празни. Приложението изобщо не получава данни от формуляра и често показва само неясно съобщение за грешка или презарежда формуляра. Това затруднява разпознаването на грешката.

Какви стойности препоръчва php.net заради PHP2Shell?

Като преходна мярка до актуализацията: post_max_size = 8M за приложения без качване на файлове, 32M за приложения с качване, а upload_max_filesize под това. Според php.net това не е пълна защита; само актуализацията до коригирана версия на PHP затваря уязвимостите.

Мога ли да променя post_max_size с ini_set() в кода?

Не. Според ръководството на PHP post_max_size може да се променя само на ниво директория, например в php.ini, в пула на FPM, в .user.ini или при mod_php в .htaccess. Който иска да наложи стойността, я задава с php_admin_value, тогава дори .user.ini не може да я презапише.

Източници

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

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

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

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