Pendant la phase de développement d'un programme, plutôt que d'utiliser un débogueur, nous choisissons parfois d'afficher une variable à l'écran pour vérifier sa valeur. Mais pour nous assurer que cet affichage ne pourra pas avoir lieu lorsque le site sera en production (en cas où on oublierait d'effacer l'instruction qui l'affiche), nous utilisons notre fonction maison echo_debug() (voir Fonction de débogage : echo_debug()).
Il serait intéressant d'appliquer la même logique aux messages d'erreur générés par PHP. En effet, lorsqu'un programme PHP rencontre du code pour lequel il a un message à envoyer, comme par exemple une erreur fatale, un avertissement ou l'utilisation d'une fonction obsolète, le message est automatiquement affiché à l'écran. Ce comportement est très pratique pendant la phase de développement. Cependant, une fois le site en production, ces messages peuvent ouvrir des trous de sécurité puisque le nom et le chemin du fichier concerné sont affichés.
Par exemple, si un site PHP utilise une fonction obsolète, comme par exemple mysql_query(), on obtiendra le message d'avertissement suivant :
« Deprecated: mysql_query(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in C:\... on line 26 ».
Si ce message est affiché lorsque le site est en production, l'usager malveillant saura qu'il peut exploiter les failles connues de mysql_query() sur ce site (entre autres, cette extension ne permettait pas d'effectuer des requêtes préparées). De plus, il connaîtra le chemin physique du dossier où le site Web est installé, ce qui lui ouvrira d'autres portes pour accomplir ses méfaits.
▼Publicité Le texte se poursuit plus bas
Dans le fichier php.ini, les configurations error_reporting et display_errors contrôlent la gestion et l'affichage des erreurs.
La configuration error_reporting indique s'il faut ou non gérer les erreurs de tel ou tel niveau de gravité.
Par défaut, sous AMPPS, les erreurs gérées seront consignées dans le fichier :
Sous Windows : C:\Program Files (x86)\Ampps\apache\logs\error.log
Sous Mac : /Applications/AMPPS/apache/logs/error_log
C'est une configuration dans httpd.conf qui spécifie l'utilisation de ce fichier.
# ErrorLog: The location of the error log file.
# If you do not specify an ErrorLog directive within a <VirtualHost>
# container, error messages relating to that virtual host will be
# logged here. If you *do* define an error logfile for a <VirtualHost>
# container, that host's errors will be logged there and not here.
#
ErrorLog "logs/error.log"
La configuration display_errors, quant à elle, indique si les erreurs gérées doivent être affichées à l'écran ou non.
Il est donc possible d'empêcher l'affichage des erreurs en initialisant error_reporting à 0 ou display_errors à Off. L'avantage de travailler au niveau de display_errors est qu'il sera possible de demander à PHP de garder une trace des erreurs dans un fichier journal plutôt que de les afficher. Et pour pouvoir les enregistrer, il faut qu'elles soient gérées.
Pour empêcher l'affichage des erreurs, plutôt que de modifier directement cette configuration dans le fichier php.ini, il est possible de modifier les configurations par programmation. Ceci permettra notamment d'avoir un comportement différent pendant le développement de l'application et lorsque le site sera en production.
Il est possible de modifier les configurations de php.ini par programmation à l'aide de la fonction ini_set(). La fonction error_reporting(), quant à elle, permettra en plus choisir les niveaux de messages que PHP doit gérer.
L'extrait de code suivant permet de n'afficher les erreurs PHP que lorsque le programme est en développement. Un simple changement de valeur pour la constante DEVEL modifiera les configurations.
Ex :
define('DEVEL', true);
...
if (DEVEL) {
// gère et affiche tous les niveaux d'erreurs en mode débogage
error_reporting(E_ALL);
ini_set('display_errors', '1');
}
else {
// en mode production, ne gère pas certains niveaux pour des raisons de performance (ceux précédés de ~), tel que suggéré dans php.ini
// même pour les niveaux gérés, aucun message ne sera affiché
error_reporting(E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED);
ini_set('display_errors', '0');
}
Notez bien : si le code PHP ne compile pas, aucune ligne de code ne sera exécutée et le message qui indique qu'il y a eu erreur sera toujours affiché puisque l'instruction demandant de ne pas les afficher ne sera pas exécutée.
Ce serait le cas, par exemple, si le développeur avait oublié un point-virgule à la fin d'une instruction. On obtiendrait une page blanche avec un message du genre « Parse error: syntax error ... ».
Dans ce cas, seules les configurations dans php.ini seront prises en compte.
Si votre site est publié en hébergement partagé (c'est généralement le cas pour les forfaits d'hébergement bon marché), vous n'aurez pas accès au fichier php.ini. Vous devez néanmoins vous assurer qu'en cas de plantage (les instructions ini_set() ne seront alors pas exécutées), votre site n'affiche pas un message ouvrant un trou de sécurité.
En effet, les utilisateurs malveillants pourraient tenter d'accéder à une faille de type full path disclosure, c'est-à-dire l'affichage d'un message qui donne le chemin d'accès physique du site Web sur le serveur. S'ils réussissent, ils utiliseront ce chemin pour tenter d'afficher le contenu d'un fichier sensible, comme par exemple celui qui effectue la connexion à la base de données et qui contient donc le code d'usager MySQL ainsi que son mot de passe.
Pour empêcher l'affichage des messages d'erreur PHP lors d'un plantage, il est possible, chez certains hébergeurs, d'ajouter une configuration dans le fichier .htaccess.
Ex :
php_flag display_startup_errors off
php_flag display_errors off
Ceci ne fonctionnera qu'aux conditions suivantes :
Pour savoir si les erreurs fatales seront affichées ou non, vous pouvez utiliser la fonction ini_get(). dans un fichier .php qui n'utilise aucun ini_set(). Vous obtiendrez alors la valeur de la configuration display_errors qui a été initialisée dans php.ini. Et si vous avez modifié sa valeur dans .htaccess et que le fichier est pris en compte, vous verrez alors la valeur initialisée dans .htaccess.
Ex :
echo "display_errors : " . ini_get('display_errors');
Puisque vous n'avez aucun contrôle sur les configurations qui permettent ou non d'utiliser .htaccess, vous n'aurez pas d'autre choix que de contacter votre hébergeur si vous constatez que les erreurs fatales sont affichées à l'écran.
« ini_set ». PHP. http://php.net/manual/fr/function.ini-set.php
« error_reporting ». PHP. http://php.net/manual/fr/function.error-reporting.php
« Gestion des erreurs - constantes pré-définies ». PHP http://php.net/manual/fr/errorfunc.constants.php
« Configuration à l'exécution ». PHP. http://php.net/manual/fr/errorfunc.configuration.php
« PHP The Right Way - Error Reporting ». PHP The Right Way. http://www.phptherightway.com/#error_reporting
« Les erreurs (e_all, e_warning, e_error) ». Oseox. http://oseox.fr/php/erreur.html
« Advanced PHP Error Handling via htaccess ». Perishable Press. https://perishablepress.com/advanced-php-error-handling-via-htaccess/
Site fièrement hébergé chez A2 Hosting.