Wiki Root66

Le Wiki de Root66, tuto, infos et astuces

Outils pour utilisateurs

Outils du site


durcissement_de_configuration_php

Durcissement de configuration PHP

Comme la grande majorité des logiciels, PHP est installé dans une configuration par défaut, qui est un compromis entre l'utilisabilité, la rétrocompatibilité et la sécurité. Pour un environnement de développement, cette configuration par défaut permet de faire fonctionner des applications (souvent Apache + module PHP) immédiatement sans agir sur sa configurationet aux développeurs de l'utiliser en ayant quelques infos de débogage. Quelques points de vigilance sont à prendre enconsidération pour préparer son module PHP en production.


Ci-dessous le “mémo” simple de configuration PHP durcie un minimum. Merci de bien vouloir lire la suite de l'article pour vous assurer de bien comprendre ces éléments et mesurer les potentiels impacts que cela peut avoir sur les sites hébergés.

Fichier de configuration /etc/php/7.0/apache2/php.ini (Debian) ou /etc/php.ini (RH)

expose_php = Off
display_errors = Off
display_startup_errors = Off
log_errors = On
error_log = "/path/to/file" ; facultatif si les logs Apache suffisent
session.use_only_cookies = 1
session.cookie_httponly = On
session.cookie_secure = On
session.use_strict_mode = 1
session.hash_function = 1
session.entropy_length = 128
allow_url_fopen = Off
allow_url_include = Off
disable_functions = system, exec, shell_exec, passthru, phpinfo, show_source, popen, proc_open
disable_functions = fopen_with_path, dbmopen, dbase_open, putenv, move_uploaded_file
disable_functions = chdir, mkdir, rmdir, chmod, rename
disable_functions = filepro, filepro_rowcount, filepro_retrieve, posix_mkfifo
variables_order = "GPCS"
file_uploads = Off ;sauf si telechargement autorisés
upload_max_filesize = xM
open_basedir = "/path" ; chemin limite autorisé pour l'ouverture de fichier par PHP

Explications de chaque directive ci-dessous.

Supprimer l'entête de réponse PHP

L'entête HTTP X-Powered-By indiquant la version de PHP exécutée côté serveur est retournée par défaut. Cette information aide l'attaquant à collecter des informations techniques sur sa cible et peut lui permettre de déduire si les composants sont à jour ou ont des vulnérabilités connues. Pour supprimer cette entête via la configuration PHP :

expose_php = Off

Supprimer l'affichage des erreurs

Les messages d'erreurs retournés dans la réponse HTTP permettent à un attaquant de découvrir plus facilement des vulnérabilités. Par exemple, si lors de l'affichage d'une page (généralement en altérant un des paramètres), une erreur relative à l'exécution SQL est retournée, cela signifie que l'URL est vulnérable à une injection SQL.

Exemple d'affichage d'une erreur

MySQL sur un site PHP : Query SELECT name_tissue_type FROM perox, peroxtissue_type, tissue_type WHERE id= AND id=id_peroxtissue_type AND id_tissue_typeperoxtissue_type=id_tissue_type ORDER BY name_tissue_type
error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AND id=id_peroxtissue_type AND id_tissue_typeperoxtissue_type=i' at line 6

L'affichage des erreurs peut aussi permettre de détecter des vulnérabilités de type inclusion de fichiers. D'une façon générale, y compris pour le confort de l'utilisateur, les messages d'erreurs techniques détaillés ne devraient jamais être exposés. Pour cela, il est nécessaire d'inclure ces 2 paramètres dans la configuration PHP :

display_errors = Off
display_startup_errors = Off

Journaliser les erreurs

Les journaux sont essentiels pour diagnostiquer les erreurs mais peuvent aussi aider à analyser un incident de sécurité. C'est pourquoi, il est important de s'assurer que PHP journalise ses erreurs avec la directive log_errors = On (par défaut, elles ne le sont pas). Dans le cas d'exécution de PHP dans le module Apache, les erreurs seront écrites dans le fichier des erreurs Apache. Il est néanmoins possible également d'isoler les erreurs PHP dans un fichier dédié, ce qui permet également de journaliser les erreurs dans le cas d'exécution de scripts PHP en CLI hors module Apache.

log_errors = On
error_log = "/path/to/file" ; Facultatif si les journaux Apache sont suffisant

Plus d'infos sur les logs en PHP : https://www.loggly.com/ultimate-guide/php-logging-basics/

Sécuriser les cookies

La sécurisation des cookies nécessite plusieurs modifications. Tout d'abord, la directive session.use_only_cookies = 1, spécifie que les identifiants de sessions ne peuvent transiter que par cookies, ce qui interdira le passage par URL (ex. : www.example.com/index.php?PHPSESSID=a43d678cb12adf08eb6). La directive session.cookie_httponly = On interdit la lecture du cookie depuis Javascript (objet document.cookie). Cette mesure prévient tout particulièrement des techniques de vol de session via XSS. La directive session.cookie_secure = On interdit le passage du cookie hors HTTPS. Cette mesure prévient d'un éventuel défaut de configuration du site et des attaques visant à voler les sessions après abaissement des requêtes de HTTPS à HTTP. La directive session.use_strict_mode = 1 permet de se prémunir contre les attaques par fixation de session. Le module Apache créera systématiquement un nouvel identifiant de session lors de la visite d'un utilisateur, il refusera tout identifiant envoyé par le navigateur. La directive session.cookie_lifetime = 7200 indique la durée de vie par défaut de la session. La valeur 7200 indique qu'après 2h d'inactivité (à adapter au contexte de l'application) la session sera détruite. La valeur par défaut 0 indique une session dépendante du redémarrage du navigateur. Enfin les directives session.hash_function = 1 et session.entropy_length = 128 indiquent à PHP d'utiliser des identifiants de session en SHA1 et l'entropie nécessaire pour les générer.

Note : la valeur par défaut est de 32 bits, l'OWASP recommande 64 bits, l'ANSSI recommande 128 bits.

session.use_only_cookies = 1
session.cookie_httponly = On
session.cookie_secure = On
session.use_strict_mode = 1
session.hash_function = 1
session.entropy_length = 128
session.cookie_lifetime = 7200

Désactiver l'inclusion de fichier distant

Les fonctions fopen et include permettent de lire ou d'inclure du contenu distant depuis le code PHP. L'inclusion de fichier distant mal utilisée peut autoriser un attaquant à charger un code arbitraire et prendre le contrôle du serveur. C'est pourquoi il est recommandé d'interdire l'inclusion de fichiers distants avec la directive allow_url_include = Off. En complément, si le site hébergé n'a pas besoin de récupérer du contenu tiers (appels de Web Services, API), il est possible d'interdire le chargement de contenu distant avec la directive allow_url_fopen = Off.

allow_url_fopen = Off
allow_url_include = Off

Désactiver les fonctions vulnérables ou dangereuses

La configuration de PHP permet d'interdire l'usage de certaines fonctions. Cela peut permettre de réduire les possibilités d'un attaquant qui serait parvenu à obtenir une possibilité d'exécution de code en complexifiant la suite de son attaque. Typiquement, les fonctions permettant l'exécution de commandes systèmes (shell, shell_exec,…), si elle ne sont pas nécessaires pour l'application hébergée, peuvent être interdites. Aussi, les fonctions de bas niveau de PHP ou encore toute fonction contenant des vulnérabilités connues peuvent être désactivées. Cela se fait par la directive disable_functions. Il reste nécessaire de s'assurer de ne pas désactiver une fonction indispensable au fonctionnement de l'application hébergée. En cas d'effet de bord, privilégiez la désactivation des fonctions system, exec, shell_exec, passthru prioritairement.

; Liste extraite du guide OWASP
disable_functions = system, exec, shell_exec, passthru, phpinfo, show_source, popen, proc_open
disable_functions = fopen_with_path, dbmopen, dbase_open, putenv, move_uploaded_file
disable_functions = chdir, mkdir, rmdir, chmod, rename
disable_functions = filepro, filepro_rowcount, filepro_retrieve, posix_mkfifo

Sécuriser l'upload

Si l'application Web ne nécessite pas de fonctionnalités d'upload, alors il est préférable de la désactiver avec la directive file_uploads = Off. Dans le cas contraire, positionner un répertoire spécifique aux uploads et indiquer une taille limite desfichiers.

file_uploads = Off ;sauf si telechargement autorisés
upload_max_filesize = xM

Limiter l'accès de PHP sur le système

Dans le cas où un attaquant aurait découvert une inclusion de fichier local (LFI) ou de traversée de répertoire (DirectoryTraversal), il pourra alors consulter d'autres fichiers sensibles du système (dans /etc par exemple). De la même manière, s'il parvient à faire exécuter un peu de code PHP arbitraire, il cherchera à sortir de l'arborescence du site. La directive open_basedir permet de spécifier un répertoire restreint à l'ouverture de fichier (par exemple /var/www/html). Ainsi, l'attaquant ne pourra pas utiliser PHP pour aller chercher d'autres fichiers à l'extérieur de ce répertoire. Il faut rester vigilantaux effets de bords. Classiquement, certains CMS ou applications Web vont stocker ou gérer les téléchargements dans /tmp. S'il n'est pas possible de modifier ce chemin dans le paramétrage du CMS, l'utilisation d'open_basedir va vraisemblablement impacter les fonctionnalités.

open_basedir = /path/

Plus d'infos

Les recommandations listées ci-dessus constituent un niveau minimal de durcissement de configuration. La configuration peut être différenciée entre la configuration PHP du module Apache et la configuration PHP en CLI. D'autres mesures telles que des spécifications plus fortes des chemins et domaines des cookies, l'affinage des logs pourraientêtre évoquées mais nécessite de s'intéresser aux spécificités des sites hébergés. Vous pouvez consulter la Cheat Sheet de l'OWASP sur PHP ou rechercher “Hardening PHP Configuration” dans un moteurde recherche.

durcissement_de_configuration_php.txt · Dernière modification : 2021/11/19 08:42 de zenzla