En bref : post_max_size limite la taille totale d'une requête POST, upload_max_filesize le fichier individuel ; selon le manuel PHP, les valeurs par défaut sont 8M et 2M. Les valeurs doivent correspondre aux limites du serveur web et de l'application, sinon les uploads échouent sans message clair. Jusqu'à la mise à jour PHP2Shell, php.net conseille post_max_size = 8M sans uploads ou 32M avec uploads, upload_max_filesize en dessous, défini de façon à ce que les applications ne l'écrasent pas.
Quand le formulaire de candidature se tait soudain
Après les mesures transitoires pour PHP2Shell, de nombreux administrateurs ont abaissé post_max_size. Quelques jours plus tard, le service du personnel signale que les candidatures n'arrivent plus. Le formulaire se recharge simplement, sans message d'erreur. La raison : la requête avec trois pièces jointes PDF dépassait la nouvelle limite, et PHP a rejeté les données du formulaire.
L'exemple illustre le problème de fond. Les limites d'upload agissent à plusieurs endroits à la fois, et chaque endroit réagit différemment en cas de dépassement. Qui connaît la chaîne peut régler les valeurs de façon à protéger sans perturber l'exploitation. La manière dont PHP traite les uploads en interne est expliquée dans Comment PHP traite les uploads de fichiers ; la programmation sûre des fonctions d'upload est décrite dans Mettre en œuvre les uploads de fichiers en PHP en toute sécurité.
La chaîne des limites d'upload
Une requête traverse plusieurs limites avant que l'application ne la voie. Les indications suivantes proviennent des documentations de Nginx, d'Apache et de PHP :
| Endroit | Paramètre | Valeur par défaut selon la doc | En cas de dépassement |
|---|---|---|---|
| Nginx | client_max_body_size |
1m | erreur 413 renvoyée au navigateur |
| Apache à partir de 2.4.54 | LimitRequestBody |
1 GiB (jusqu'à 2.4.53 : illimité) | réponse d'erreur au lieu du traitement |
| PHP | post_max_size |
8M | $_POST et $_FILES vides |
| PHP | upload_max_filesize |
2M | fichier refusé avec un code d'erreur |
| PHP | max_file_uploads |
20 | les fichiers supplémentaires sont ignorés |
| PHP | max_input_vars |
1000 | les champs de formulaire supplémentaires manquent |
Il en résulte une règle simple : upload_max_filesize inférieur à post_max_size, post_max_size inférieur à la limite du serveur web. Le manuel PHP recommande en outre que memory_limit soit en général supérieur à post_max_size. Pendant la mesure transitoire PHP2Shell avec memory_limit=-1, ce rôle est tenu par la limite au niveau du conteneur ou de cgroup ; plus de détails dans Bien régler memory_limit.
post_max_size après PHP2Shell : ce que conseille php.net
Dans son avis de sécurité du 21 octobre 2026, php.net cite, pour les serveurs sans mise à jour, de faibles limites de requête parmi les mesures transitoires. Elles réduisent le risque de certaines voies d'attaque, mais ne constituent expressément pas une protection complète :
- Sans upload de fichiers :
post_max_size = 8M. - Avec upload de fichiers :
post_max_size = 32M. - Dans les deux cas : maintenir
upload_max_filesizeen dessous depost_max_size. - À envisager en plus : des limites dans le serveur web ou le proxy pour la taille décodée de la requête, le nombre de champs de saisie, le nombre de parties multipart, le nombre d'en-têtes et la profondeur d'imbrication. Selon php.net, ces limites doivent aussi couvrir les requêtes sans indication exploitable de
Content-Length.
Les valeurs doivent être placées là où les applications ne peuvent pas les écraser. Comme post_max_size et upload_max_filesize sont modifiables au niveau du répertoire selon le manuel, un .user.ini ou, avec mod_php, un .htaccess pourrait sinon les relever :
; Pool FPM du site, avec uploads (transition jusqu'à la mise à jour)
php_admin_value[post_max_size] = 32M
php_admin_value[upload_max_filesize] = 24M
php_admin_value[max_file_uploads] = 5
Dans le serveur web, placez la limite juste au-dessus, afin que les requêtes trop volumineuses n'arrivent même pas jusqu'à PHP :
# Nginx, dans le bloc server ou location
client_max_body_size 32m;
# Apache, dans le VirtualHost : 32 MiB en octets
LimitRequestBody 33554432
Rechargez ensuite tous les workers PHP et le serveur web. L'aperçu de toutes les mesures transitoires figure dans Mesures immédiates si vous ne pouvez pas encore appliquer le correctif. La question de savoir si et comment les requêtes d'upload peuvent en outre être filtrées au niveau du proxy est examinée dans Filtrer les requêtes d'upload en bordure.
Après chaque modification, testez les formulaires avec les requêtes légitimes les plus volumineuses : candidatures avec plusieurs pièces jointes, imports de produits, galeries d'images. Une valeur trop serrée paralyse des processus métier sans que personne ne voie de message d'erreur.
Déterminer la bonne valeur pour votre site
Au lieu de valeurs générales, un bref état des lieux vaut la peine. Listez tous les formulaires avec upload et notez le plus gros fichier légitime et le plus grand nombre de fichiers simultanés. Il en résulte le besoin : upload_max_filesize couvre le plus gros fichier individuel, post_max_size la somme de tous les fichiers d'une requête plus une petite réserve pour les champs de formulaire.
Si le besoin dépasse 32M, il ne correspond pas à la recommandation transitoire de php.net. C'est alors une raison de plus d'avancer la mise à jour. Les gros uploads peuvent aussi être traités via un sous-domaine dédié avec son propre pool, afin que le reste du site conserve des limites étroites.
Après la mise à jour vers 8.5.12, 8.4.27, 8.3.36, 8.2.35 ou un backport confirmé, vous pouvez réaligner les valeurs sur le besoin réel. Elles ne devraient toutefois pas être plus généreuses que nécessaire : toute limite qui dépasse le besoin agrandit la surface d'attaque sans utilité. Si un site n'a aucun besoin d'uploads, file_uploads = Off est la solution la plus propre.
Interpréter correctement les symptômes
Quand les uploads échouent, le comportement révèle quelle limite s'applique. Une page avec erreur 413 vient du serveur web. Un formulaire qui se recharge sans message ou signale « requête invalide » indique des données $_POST vides, donc post_max_size. Un message de l'application concernant un fichier individuel correspond à upload_max_filesize. Et des champs manquants dans de très grands formulaires, par exemple pour des variantes de produits, plaident pour max_input_vars. Le journal d'erreurs PHP contient en général, en cas de dépassement de post_max_size, un avertissement indiquant la taille de la requête.
Pour que les utilisateurs ne restent pas désemparés, l'application devrait reconnaître ce cas. Le manuel PHP propose pour cela une méthode simple : le formulaire transmet un marqueur dans l'adresse, par exemple ?processed=1. Si ce marqueur arrive mais que $_POST et $_FILES sont vides, la requête était trop volumineuse, et l'application peut afficher un message compréhensible indiquant la taille autorisée.
Comment PHP SOS aide-t-il concrètement ?
- Nous recensons toutes les voies d'upload de vos sites et déterminons les tailles réellement nécessaires.
- Nous réglons de façon cohérente les limites du serveur web, de PHP et des pools, verrouillées contre l'écrasement, y compris les valeurs transitoires de php.net.
- Nous testons formulaires, imports et uploads après le changement et ajustons les valeurs de manière ciblée.
- Dans le cadre du durcissement de serveur, nous ramenons les valeurs, après la mise à jour, au besoin durable.
Questions fréquentes
Quelle est la différence entre post_max_size et upload_max_filesize ?
upload_max_filesize limite la taille d'un fichier téléversé individuel. post_max_size limite l'ensemble des données d'une requête POST, donc tous les fichiers et champs de formulaire réunis. Selon le manuel PHP, post_max_size doit donc être supérieur à upload_max_filesize.
Que se passe-t-il si une requête dépasse post_max_size ?
Selon le manuel PHP, $_POST et $_FILES sont alors vides. L'application ne reçoit donc aucune donnée de formulaire et n'affiche souvent qu'un message d'erreur peu clair ou recharge le formulaire. Cela rend cette erreur difficile à reconnaître.
Quelles valeurs php.net recommande-t-il à cause de PHP2Shell ?
Comme mesure transitoire jusqu'à la mise à jour : post_max_size = 8M pour les applications sans upload de fichiers, 32M pour les applications avec uploads, et upload_max_filesize en dessous. Selon php.net, ce n'est pas une protection complète ; seule la mise à jour vers une version corrigée de PHP ferme les failles.
Puis-je modifier post_max_size avec ini_set() dans le code ?
Non. Selon le manuel PHP, post_max_size n'est modifiable qu'au niveau du répertoire, par exemple dans php.ini, dans le pool FPM, dans .user.ini ou, avec mod_php, dans .htaccess. Pour imposer la valeur, définissez-la avec php_admin_value ; un .user.ini ne peut alors pas non plus l'écraser.