Situation actuelle : PHP2Shell. Deux failles PHP critiques (CVSS 9.2) permettent d'exécuter du code malveillant sans authentification. Correctifs disponibles depuis le 21 octobre 2026.Ce qu'il faut faire maintenant →

php_admin_value : verrouiller les paramètres contre l'écrasement

Un paramètre de sécurité sert à peu de chose si l'application le modifie à nouveau avec une ligne de code. Avec php_admin_value et php_admin_flag, vous fixez des valeurs de façon contraignante pour PHP-FPM et Apache.

État 6 min de lectureDurcissement et configuration

En bref : php_admin_value et php_admin_flag définissent des paramètres PHP dans le pool PHP-FPM ou dans la configuration d'Apache de telle sorte que les applications ne puissent les modifier ni par ini_set() ni par .htaccess. php.net exige précisément cela pour les mesures transitoires PHP2Shell, par exemple pour memory_limit=-1. Après la définition, le service doit être redémarré et la valeur vérifiée dans le contexte web.

Pourquoi « défini » ne veut pas dire « verrouillé »

Dans les jours qui ont suivi le 21 octobre 2026, de nombreux administrateurs ont inscrit les mesures transitoires de php.net dans leur php.ini. Un détail de la recommandation a souvent été perdu de vue : memory_limit=-1 doit être défini de façon que les applications ne puissent pas l'écraser. php.net cite expressément pour cela php_admin_value dans le pool FPM ou dans la configuration d'Apache.

La raison est simple. De nombreux CMS, boutiques et frameworks définissent leurs propres valeurs, par exemple une limite de mémoire plus élevée pour les imports. Si la valeur ne figure que dans le php.ini, l'application l'écrase dès l'appel suivant. La mesure de protection existe alors sur le papier, mais pas dans le processus en cours d'exécution.

Cela ne concerne pas seulement PHP2Shell. Tout durcissement, de la désactivation des sorties d'erreur aux limites d'upload, n'est aussi solide que son niveau le plus faible.

Qui peut modifier les paramètres PHP

PHP connaît quatre modes de modification. Chaque paramètre en a un, et il détermine à quels endroits il peut être défini. Les significations proviennent du manuel PHP.

Mode Où la valeur peut être définie Exemples
INI_USER dans le script via ini_set() et dans .user.ini quelques valeurs d'exécution
INI_PERDIR php.ini, .htaccess, httpd.conf, .user.ini post_max_size, session.upload_progress.enabled
INI_SYSTEM uniquement php.ini ou httpd.conf file_uploads, disable_functions
INI_ALL partout, y compris via ini_set() memory_limit, display_errors, open_basedir

Les valeurs INI_ALL sont surtout dangereuses : elles peuvent être modifiées depuis n'importe quel script. Les valeurs INI_PERDIR ne peuvent certes pas être modifiées par ini_set(), mais elles le peuvent via un .htaccess avec mod_php ou un .user.ini avec PHP-FPM. Qui dispose de droits d'écriture dans la racine web, donc aussi du code injecté, peut créer de tels fichiers.

php_admin_value dans le pool FPM et dans Apache

Avec PHP-FPM, les valeurs figurent dans le fichier de pool. Le manuel PHP précise : les valeurs définies avec php_admin_value et php_admin_flag ne peuvent pas être écrasées par ini_set(). Pour les valeurs de type activé/désactivé, utilisez php_admin_flag, pour toutes les autres php_admin_value.

; /etc/php/8.3/fpm/pool.d/seite1.conf (extrait)
[seite1]
user = seite1
group = seite1
listen = /run/php/seite1.sock

php_admin_value[memory_limit] = -1
php_admin_value[post_max_size] = 32M
php_admin_value[upload_max_filesize] = 24M
php_admin_flag[session.upload_progress.enabled] = off
php_admin_flag[display_errors] = off
php_admin_value[error_log] = /var/log/php/seite1-fehler.log
php_admin_value[open_basedir] = /var/www/seite1/:/tmp/seite1/

Selon php.net, memory_limit=-1 n'a sa place dans la configuration qu'avec une limite mémoire au niveau du conteneur ou de cgroup. La manière d'y parvenir avec systemd est décrite dans l'article Définir des limites de mémoire avec systemd et cgroups.

Avec Apache et mod_php, les directives doivent figurer dans la configuration du serveur ou le VirtualHost. Selon le manuel PHP, elles ne sont pas autorisées dans .htaccess, et une fois définies, ni .htaccess ni ini_set() ne peuvent les modifier.

<VirtualHost *:443>
    ServerName www.example.de
    DocumentRoot /var/www/seite1/public
    <IfModule php_module>
        php_admin_value memory_limit -1
        php_admin_value post_max_size 32M
        php_admin_value upload_max_filesize 24M
        php_admin_flag session.upload_progress.enabled off
        php_admin_flag display_errors off
    </IfModule>
</VirtualHost>

Deux subtilités du manuel : pour supprimer une valeur définie auparavant, utilisez none comme valeur. Et les constantes PHP comme E_ALL n'ont aucune signification dans la configuration d'Apache ; pour error_reporting, vous devez y indiquer la valeur numérique.

Quelles valeurs verrouiller

Tous les paramètres n'ont pas à être verrouillés. Cela a du sens pour tout ce qui touche à la sécurité ou sert de mesure transitoire :

  1. Les valeurs transitoires PHP2Shell de php.net : memory_limit, post_max_size, upload_max_filesize, session.upload_progress.enabled et, sur PHP 8.5, fatal_error_backtraces.
  2. Sortie d'erreur et journalisation : display_errors, display_startup_errors, log_errors, error_log.
  3. Accès aux fichiers et isolation : open_basedir, upload_tmp_dir, session.save_path.
  4. Accès réseau depuis PHP : allow_url_include et, si l'application n'en a pas besoin, allow_url_fopen.
  5. Fonctions bloquées via disable_functions, qui dans le pool complètent la liste du php.ini et ne la remplacent pas, selon le manuel. Détails dans le guide Utiliser disable_functions correctement.

Pour session.upload_progress.enabled, le verrouillage est particulièrement important, car la valeur pourrait sinon être réactivée via un .user.ini. Plus de détails dans Désactiver session.upload_progress : correctement et durablement.

Vérifier que le verrou fonctionne

Après chaque modification, redémarrez le service et vérifiez la valeur dans le contexte web. Un court fichier de test, supprimé aussitôt, montre si le pool maintient la valeur même si l'application veut la modifier :

<?php
// Fichier de test : le déposer brièvement, l'appeler une fois via le domaine, le supprimer aussitôt
header('Content-Type: text/plain');
$vorher = ini_get('memory_limit');
$versuch = @ini_set('memory_limit', '256M');
echo "memory_limit: $vorher\n";
echo 'Änderung per ini_set() ', ($versuch === false ? 'blockiert' : 'MÖGLICH'), "\n";

On attend -1 et « blockiert » (le script affiche ses messages en allemand). Si la sortie indique « MÖGLICH », la valeur n'est pas définie via php_admin_value ou le service n'a pas encore été redémarré. Répétez la vérification pour chaque pool et chaque version de PHP.

Astuce

Consignez de façon centralisée les valeurs verrouillées, par exemple dans un modèle de pool ou dans votre gestion de configuration. Les panneaux d'hébergement écrasent parfois les fichiers de pool modifiés à la main lors de l'enregistrement suivant ; les valeurs doivent alors figurer dans les champs prévus par le panneau.

La manière dont PHP ordonne globalement ses niveaux de configuration est expliquée dans Le php.ini expliqué : structure, niveaux et priorité. Les mesures transitoires complètes figurent dans Mesures immédiates si vous ne pouvez pas encore appliquer le correctif.

Conclusion : verrouillé, c'est vraiment défini

Les mesures transitoires de php.net pour PHP2Shell ont fait prendre conscience d'une distinction souvent négligée auparavant : pour de nombreux paramètres, une valeur dans le php.ini n'est qu'une suggestion, une valeur dans php_admin_value est une consigne. Pour des valeurs de confort comme le fuseau horaire, la différence est sans importance. Pour les paramètres de sécurité et les mesures transitoires, elle décide si la mesure s'applique réellement en exploitation.

L'effort est raisonnable : une poignée de lignes par pool ou VirtualHost, un redémarrage, une courte vérification. Gardez la liste des valeurs verrouillées courte et motivée, afin que les développeurs puissent comprendre pourquoi leur application ne peut pas modifier une valeur. Et tenez la liste à jour dans vos modèles, pour que les nouveaux sites en héritent automatiquement.

Comment PHP SOS aide-t-il concrètement ?

  • Lire les niveaux : nous déterminons pour chaque site quelles valeurs du php.ini, du pool, d'Apache, de .htaccess ou de .user.ini s'appliquent réellement.
  • Poser les verrous : nous inscrivons les valeurs pertinentes pour la sécurité et les mesures transitoires PHP2Shell sous forme de php_admin_value ou php_admin_flag et redémarrons les services.
  • Tester l'application : nous vérifions que l'application fonctionne sans erreur avec les valeurs verrouillées et analysons le journal d'erreurs.
  • Entretenir les modèles : dans le cadre du durcissement de serveur, nous reprenons les valeurs dans les modèles de pool et la documentation.

Questions fréquentes

Quelle est la différence entre php_value et php_admin_value ?

Les deux définissent un paramètre PHP. Les valeurs de php_value peuvent être modifiées plus tard par l'application, par exemple avec ini_set() ou .htaccess. Les valeurs de php_admin_value et php_admin_flag sont, selon le manuel PHP, verrouillées pour ini_set(), et avec Apache aussi pour .htaccess.

Puis-je écrire php_admin_value dans un fichier .htaccess ?

Non. Selon le manuel PHP, php_admin_value n'est pas autorisé dans les fichiers .htaccess. Il a sa place dans la configuration du serveur Apache ou le VirtualHost, et avec PHP-FPM dans le fichier de pool.

Que se passe-t-il si une application veut modifier une valeur verrouillée ?

L'appel à ini_set() échoue et renvoie false, la valeur verrouillée reste en place. Les applications bien programmées s'en accommodent. Vérifiez malgré tout le journal d'erreurs et les fonctions principales après le changement.

Dois-je redémarrer après une modification dans le pool ?

Oui. PHP-FPM lit les fichiers de pool au démarrage ou au rechargement du service. Avec Apache et mod_php, il en va de même pour la configuration du serveur. Sans redémarrage, l'ancienne valeur continue de s'appliquer.

Peut-on étendre disable_functions dans le pool ?

Oui, avec une particularité : selon le manuel PHP, disable_functions dans le pool FPM n'écrase pas les valeurs du php.ini, mais les complète. Le pool peut donc bloquer d'autres fonctions, mais pas en libérer.

Sources

Contact immédiat

Chaque heure compte. Écrivez-nous maintenant.

Décrivez brièvement votre système, votre version de PHP et ce que vous avez observé. Nous vous répondons, faisons le point et travaillons à distance jusqu'à la clôture et la documentation de l'incident.

Aide immédiate