Kort gezegd: post_max_size begrenst de totale grootte van een POST-verzoek, upload_max_filesize het afzonderlijke bestand; standaard zijn dat volgens de PHP-handleiding 8M en 2M. De waarden moeten passen bij de grenzen in de webserver en in de applicatie, anders mislukken uploads zonder duidelijke melding. Tot de PHP2Shell-update adviseert php.net post_max_size = 8M zonder uploads of 32M met uploads, upload_max_filesize daaronder, zo ingesteld dat applicaties het niet overschrijven.
Als het sollicitatieformulier opeens zwijgt
Na de overbruggingsmaatregelen voor PHP2Shell hebben veel beheerders post_max_size verlaagd. Enkele dagen later meldt de personeelsafdeling dat sollicitaties niet meer aankomen. Het formulier laadt gewoon opnieuw, een foutmelding is er niet. De reden: het verzoek met drie pdf-bijlagen was groter dan de nieuwe grens en PHP heeft de formuliergegevens verworpen.
Het voorbeeld toont het basisprobleem. Uploadgrenzen werken op meerdere plaatsen tegelijk en elke plaats reageert anders als ze wordt overschreden. Wie de keten kent, kan de waarden zo instellen dat ze beschermen zonder het bedrijfsproces te verstoren. Hoe PHP uploads intern verwerkt, legt Hoe PHP bestandsuploads verwerkt uit; de veilige programmering van uploadfuncties beschrijft Bestandsuploads in PHP veilig implementeren.
De keten van uploadgrenzen
Een verzoek passeert meerdere grenzen voordat de applicatie het ziet. De volgende gegevens komen uit de documentatie van Nginx, Apache en PHP:
| Plaats | Instelling | Standaard volgens documentatie | Bij overschrijding |
|---|---|---|---|
| Nginx | client_max_body_size |
1m | Fout 413 naar de browser |
| Apache vanaf 2.4.54 | LimitRequestBody |
1 GiB (tot 2.4.53: onbegrensd) | Foutantwoord in plaats van verwerking |
| PHP | post_max_size |
8M | $_POST en $_FILES leeg |
| PHP | upload_max_filesize |
2M | Bestand wordt met foutcode geweigerd |
| PHP | max_file_uploads |
20 | verdere bestanden worden genegeerd |
| PHP | max_input_vars |
1000 | verdere formuliervelden ontbreken |
Daaruit volgt een eenvoudige regel: upload_max_filesize kleiner dan post_max_size, post_max_size kleiner dan de grens in de webserver. De PHP-handleiding adviseert bovendien dat memory_limit over het algemeen groter is dan post_max_size. Tijdens de PHP2Shell-overbruggingsmaatregel met memory_limit=-1 neemt de grens via container of cgroup die rol over; meer daarover onder memory_limit juist instellen.
post_max_size na PHP2Shell: wat php.net adviseert
In de beveiligingsmelding van 21-10-2026 noemt php.net voor servers zonder update lage verzoekgrenzen als een van de overbruggingsmaatregelen. Ze verkleinen het risico van afzonderlijke aanvalswegen, maar zijn uitdrukkelijk geen volledige bescherming:
- Zonder bestandsuploads:
post_max_size = 8M. - Met bestandsuploads:
post_max_size = 32M. - In beide gevallen:
upload_max_filesizeonderpost_max_sizehouden. - Daarnaast overwegen: grenzen in de webserver of proxy voor de gedecodeerde verzoekgrootte, het aantal invoervelden, het aantal multipart-delen, het aantal kopregels en de nestdiepte. Volgens php.net moeten deze grenzen ook verzoeken zonder bruikbare
Content-Length-vermelding dekken.
De waarden horen daar te staan waar applicaties ze niet kunnen overschrijven. Omdat post_max_size en upload_max_filesize volgens de handleiding op mapniveau te wijzigen zijn, zou een .user.ini of bij mod_php een .htaccess ze anders weer kunnen verhogen:
; FPM-pool van de website, met uploads (overbrugging tot de update)
php_admin_value[post_max_size] = 32M
php_admin_value[upload_max_filesize] = 24M
php_admin_value[max_file_uploads] = 5
In de webserver trekt u de grens net daarboven, zodat te grote verzoeken PHP helemaal niet bereiken:
# Nginx, in het server- of location-blok
client_max_body_size 32m;
# Apache, in de VirtualHost: 32 MiB in bytes
LimitRequestBody 33554432
Laad daarna alle PHP-workers en de webserver opnieuw. Het overzicht van alle overbruggingsmaatregelen staat onder Noodmaatregelen als u nog niet kunt patchen. Of en hoe uploadverzoeken daarnaast aan de proxy te filteren zijn, belicht Uploadverzoeken aan de rand filteren.
Test na elke wijziging de formulieren met de grootste legitieme verzoeken: sollicitaties met meerdere bijlagen, productimports, fotogalerijen. Een te krappe waarde legt bedrijfsprocessen lam zonder dat iemand een foutmelding ziet.
De juiste waarde voor uw website vaststellen
In plaats van algemene waarden loont een korte inventarisatie. Maak een lijst van alle formulieren met uploads en noteer het grootste legitieme bestand en het hoogste aantal gelijktijdige bestanden. Daaruit volgt de behoefte: upload_max_filesize dekt het grootste afzonderlijke bestand, post_max_size de som van alle bestanden van een verzoek plus wat reserve voor formuliervelden.
Ligt de behoefte boven 32M, dan past ze niet bij het overbruggingsadvies van php.net. Dat is dan een extra reden om de update naar voren te halen. Grote uploads kunnen ook via een eigen subdomein met een eigen pool worden afgehandeld, zodat de rest van de website krappe grenzen houdt.
Na de update naar 8.5.12, 8.4.27, 8.3.36, 8.2.35 of een bevestigde backport kunt u de waarden weer op de werkelijke behoefte afstemmen. Ruimer dan nodig mogen ze toch niet zijn: elke grens die boven de behoefte uitgaat, vergroot het aanvalsoppervlak zonder nut. Heeft een website helemaal geen uploads nodig, dan is file_uploads = Off de zuiverste oplossing.
Foutbeelden juist duiden
Als uploads mislukken, verraadt het gedrag welke grens ingrijpt. Een pagina met fout 413 komt van de webserver. Een formulier dat zonder melding opnieuw laadt of „ongeldig verzoek” meldt, wijst op lege $_POST-gegevens, dus op post_max_size. Een melding van de applicatie over een afzonderlijk bestand past bij upload_max_filesize. En ontbrekende velden in zeer grote formulieren, bijvoorbeeld bij productvarianten, wijzen op max_input_vars. Het PHP-foutenlog bevat bij een overschreden post_max_size in de regel een waarschuwing met de grootte van het verzoek.
Zodat gebruikers niet ratloos achterblijven, moet de applicatie dit geval herkennen. De PHP-handleiding stelt daarvoor een eenvoudige weg voor: het formulier geeft een markering mee in het adres, bijvoorbeeld ?processed=1. Komt die markering aan, maar zijn $_POST en $_FILES leeg, dan was het verzoek te groot en kan de applicatie een begrijpelijke melding met de toegestane grootte tonen.
Hoe helpt PHP SOS concreet?
- Wij inventariseren alle uploadwegen van uw websites en stellen de werkelijk benodigde groottes vast.
- Wij stellen webserver-, PHP- en poolgrenzen op elkaar af en vergrendelen ze tegen overschrijven, inclusief de overbruggingswaarden van php.net.
- Wij testen formulieren, imports en uploads na de omschakeling en passen waarden gericht aan.
- In het kader van de serverhardening brengen wij de waarden na de update terug naar de blijvende behoefte.
Veelgestelde vragen
Wat is het verschil tussen post_max_size en upload_max_filesize?
upload_max_filesize begrenst de grootte van één geüpload bestand. post_max_size begrenst de totale gegevens van een POST-verzoek, dus alle bestanden en formuliervelden samen. Volgens de PHP-handleiding moet post_max_size daarom groter zijn dan upload_max_filesize.
Wat gebeurt er als een verzoek groter is dan post_max_size?
Volgens de PHP-handleiding zijn $_POST en $_FILES dan leeg. De applicatie ontvangt dus helemaal geen formuliergegevens en toont vaak alleen een onduidelijke foutmelding of laadt het formulier opnieuw. Dat maakt deze fout moeilijk te herkennen.
Welke waarden adviseert php.net vanwege PHP2Shell?
Als overbruggingsmaatregel tot de update: post_max_size = 8M voor applicaties zonder bestandsuploads, 32M voor applicaties met uploads, en upload_max_filesize daaronder. Dat is volgens php.net geen volledige bescherming; alleen de update naar een verholpen PHP-versie sluit de kwetsbaarheden.
Kan ik post_max_size met ini_set() in de code wijzigen?
Nee. Volgens de PHP-handleiding is post_max_size alleen op mapniveau te wijzigen, bijvoorbeeld in php.ini, in de FPM-pool, in .user.ini of bij mod_php in .htaccess. Wie de waarde wil afdwingen, stelt haar in met php_admin_value; dan kan ook een .user.ini haar niet overschrijven.