Krótko: post_max_size ogranicza całkowity rozmiar żądania POST, upload_max_filesize pojedynczy plik; domyślnie według podręcznika PHP jest to 8M i 2M. Wartości muszą pasować do limitów w serwerze WWW i w aplikacji, w przeciwnym razie uploady kończą się niepowodzeniem bez jasnego komunikatu. Do czasu aktualizacji PHP2Shell php.net zaleca post_max_size = 8M bez uploadu lub 32M z uploadem, a upload_max_filesize poniżej tej wartości, ustawione tak, aby aplikacje go nie nadpisywały.
Gdy formularz aplikacyjny nagle milczy
Po środkach przejściowych dla PHP2Shell wielu administratorów obniżyło post_max_size. Kilka dni później dział kadr zgłasza, że aplikacje nie docierają. Formularz po prostu ładuje się od nowa, komunikatu o błędzie nie ma. Przyczyna: żądanie z trzema załącznikami PDF było większe niż nowy limit, a PHP odrzucił dane formularza.
Przykład pokazuje podstawowy problem. Limity uploadu działają jednocześnie w kilku miejscach, a każde z nich reaguje inaczej po przekroczeniu. Kto zna cały łańcuch, może ustawić wartości tak, aby chroniły, nie zakłócając pracy. Jak PHP wewnętrznie przetwarza uploady, wyjaśnia artykuł Jak PHP przetwarza uploady plików; bezpieczne programowanie funkcji uploadu opisuje poradnik Bezpieczna implementacja uploadu plików w PHP.
Łańcuch limitów uploadu
Żądanie przechodzi przez kilka limitów, zanim zobaczy je aplikacja. Poniższe dane pochodzą z dokumentacji Nginx, Apache i PHP:
| Miejsce | Ustawienie | Domyślnie według dokumentacji | Po przekroczeniu |
|---|---|---|---|
| Nginx | client_max_body_size |
1m | błąd 413 dla przeglądarki |
| Apache od 2.4.54 | LimitRequestBody |
1 GiB (do 2.4.53: bez ograniczenia) | odpowiedź z błędem zamiast przetwarzania |
| PHP | post_max_size |
8M | $_POST i $_FILES puste |
| PHP | upload_max_filesize |
2M | plik odrzucony z kodem błędu |
| PHP | max_file_uploads |
20 | dalsze pliki są ignorowane |
| PHP | max_input_vars |
1000 | brakuje dalszych pól formularza |
Z tego wynika prosta zasada: upload_max_filesize mniejsze niż post_max_size, post_max_size mniejsze niż limit w serwerze WWW. Podręcznik PHP zaleca ponadto, aby memory_limit był ogólnie większy niż post_max_size. W czasie środka przejściowego PHP2Shell z memory_limit=-1 tę rolę przejmuje limit przez kontener lub cgroup; więcej w artykule Prawidłowe ustawienie memory_limit.
post_max_size po PHP2Shell: co zaleca php.net
W komunikacie bezpieczeństwa z 21.10.2026 php.net podaje dla serwerów bez aktualizacji niskie limity żądań jako jeden ze środków przejściowych. Zmniejszają one ryzyko poszczególnych dróg ataku, ale wyraźnie nie są pełną ochroną:
- Bez uploadu plików:
post_max_size = 8M. - Z uploadem plików:
post_max_size = 32M. - W obu przypadkach:
upload_max_filesizeutrzymywać poniżejpost_max_size. - Dodatkowo rozważyć: limity w serwerze WWW lub proxy dla zdekodowanego rozmiaru żądania, liczby pól wejściowych, liczby części multipart, liczby nagłówków i głębokości zagnieżdżenia. Według php.net limity te muszą obejmować także żądania bez użytecznej wartości
Content-Length.
Wartości należy umieścić tam, gdzie aplikacje nie mogą ich nadpisać. Ponieważ post_max_size i upload_max_filesize według podręcznika można zmieniać na poziomie katalogu, plik .user.ini lub przy mod_php plik .htaccess mógłby je inaczej ponownie podnieść:
; Pula FPM strony, z uploadem (przejściowo do aktualizacji)
php_admin_value[post_max_size] = 32M
php_admin_value[upload_max_filesize] = 24M
php_admin_value[max_file_uploads] = 5
W serwerze WWW limit ustawia się tuż powyżej, aby zbyt duże żądania w ogóle nie docierały do PHP:
# Nginx, w bloku server lub location
client_max_body_size 32m;
# Apache, w VirtualHost: 32 MiB w bajtach
LimitRequestBody 33554432
Następnie przeładować wszystkie procesy robocze PHP i serwer WWW. Przegląd wszystkich środków przejściowych znajduje się na stronie Środki doraźne, gdy nie mogą Państwo jeszcze załatać. Czy i jak można dodatkowo filtrować żądania uploadu na proxy, omawia artykuł Filtrowanie żądań uploadu na brzegu.
Po każdej zmianie proszę przetestować formularze z największymi uzasadnionymi żądaniami: aplikacje z wieloma załącznikami, importy produktów, galerie zdjęć. Zbyt ciasna wartość paraliżuje procesy biznesowe, nie wywołując żadnego komunikatu o błędzie.
Ustalanie właściwej wartości dla Państwa strony
Zamiast wartości zbiorczych warto krótko dokonać inwentaryzacji. Proszę wypisać wszystkie formularze z uploadem i odnotować największy uzasadniony plik oraz największą liczbę jednoczesnych plików. Z tego wynika zapotrzebowanie: upload_max_filesize pokrywa największy pojedynczy plik, post_max_size sumę wszystkich plików żądania plus niewielką rezerwę na pola formularza.
Jeśli zapotrzebowanie przekracza 32M, nie pasuje do zalecenia przejściowego php.net. Jest to wtedy kolejny powód, by przyspieszyć aktualizację. Duże uploady można też obsłużyć przez osobną subdomenę z własną pulą, aby pozostała część strony zachowała wąskie limity.
Po aktualizacji do 8.5.12, 8.4.27, 8.3.36, 8.2.35 lub potwierdzonego backportu mogą Państwo ponownie dopasować wartości do rzeczywistego zapotrzebowania. Nie powinny one jednak być hojniejsze niż to konieczne: każdy limit wykraczający poza potrzebę powiększa powierzchnię ataku bez pożytku. Jeśli strona w ogóle nie potrzebuje uploadów, najczystszym rozwiązaniem jest file_uploads = Off.
Właściwe odczytywanie objawów błędów
Gdy uploady się nie udają, zachowanie zdradza, który limit działa. Strona z błędem 413 pochodzi od serwera WWW. Formularz, który ładuje się od nowa bez komunikatu lub zgłasza „nieprawidłowe żądanie”, wskazuje na puste dane $_POST, czyli post_max_size. Komunikat aplikacji o pojedynczym pliku pasuje do upload_max_filesize. A brakujące pola w bardzo dużych formularzach, na przykład przy wariantach produktów, przemawiają za max_input_vars. Log błędów PHP zawiera przy przekroczonym post_max_size zazwyczaj ostrzeżenie z rozmiarem żądania.
Aby użytkownicy nie zostali bezradni, aplikacja powinna rozpoznawać ten przypadek. Podręcznik PHP proponuje do tego prostą drogę: formularz przekazuje znacznik w adresie, na przykład ?processed=1. Jeśli znacznik dotrze, ale $_POST i $_FILES są puste, żądanie było zbyt duże, a aplikacja może wyświetlić zrozumiały komunikat z dopuszczalnym rozmiarem.
Jak konkretnie pomaga PHP SOS?
- Inwentaryzujemy wszystkie drogi uploadu na Państwa stronach i ustalamy rzeczywiście potrzebne rozmiary.
- Ustawiamy limity serwera WWW, PHP i puli spójnie i zablokowane przed nadpisaniem, łącznie z wartościami przejściowymi z php.net.
- Testujemy formularze, importy i uploady po przestawieniu i celowo dostosowujemy wartości.
- W ramach utwardzania serwerów po aktualizacji sprowadzamy wartości z powrotem do trwałego zapotrzebowania.
Częste pytania
Jaka jest różnica między post_max_size a upload_max_filesize?
upload_max_filesize ogranicza rozmiar pojedynczego przesłanego pliku. post_max_size ogranicza całość danych żądania POST, czyli wszystkie pliki i pola formularza łącznie. Według podręcznika PHP post_max_size musi więc być większe niż upload_max_filesize.
Co się dzieje, gdy żądanie jest większe niż post_max_size?
Według podręcznika PHP $_POST i $_FILES są wtedy puste. Aplikacja nie otrzymuje więc żadnych danych formularza i często wyświetla tylko niejasny komunikat błędu albo ponownie ładuje formularz. Przez to ten błąd trudno rozpoznać.
Jakie wartości zaleca php.net ze względu na PHP2Shell?
Jako środek przejściowy do czasu aktualizacji: post_max_size = 8M dla aplikacji bez uploadu plików, 32M dla aplikacji z uploadem, a upload_max_filesize poniżej tej wartości. Według php.net nie jest to pełna ochrona; luki zamyka tylko aktualizacja do naprawionej wersji PHP.
Czy mogę zmienić post_max_size przez ini_set() w kodzie?
Nie. Według podręcznika PHP post_max_size można zmieniać tylko na poziomie katalogu, na przykład w php.ini, w puli FPM, w .user.ini lub przy mod_php w .htaccess. Kto chce wymusić wartość, ustawia ją przez php_admin_value, wtedy nie może jej nadpisać nawet .user.ini.