IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Tutoriel récapitulatif de sécurité (PHP5)

Date de publication : 12 mai 2006 , Date de mise à jour : 12 mai 2006




II. Votre configuration PHP
II-1. display_errors
Dangers
Configuration
II-2. error_reporting
Dangers
Configuration
Notes
II-3. magic_quotes
Dangers
Configuration
Notes
II-4. register_globals
Dangers
Configuration
Notes


II. Votre configuration PHP

Vous devez adapter la configuration de votre serveur à l'environnement dans lequel il est utilisé. Il n'est pas imaginable d'utiliser la même configuration pour un serveur de développement et pour un serveur en production. En effet, le développeur a besoin de toutes les informations de débogage dont il peut disposer tandis que le visiteur doit, au contraire, recevoir le minimum possible d'informations sur votre système (si ces informations l'intéressent, c'est assurément qu'il a des intentions malicieuses).
Il est possible de modifier les directives de configuration de PHP dans le fichier php.ini et parfois au moyen de fonctions PHP.


II-1. display_errors

Cette directive, comme son nom l'indique clairement, permet d'activer ou de désactiver l'affichage de toutes les erreurs par le moteur PHP.


Dangers

Pour un utilisateur inexpérimenté, le danger est nul. Il se demandera ce qu'il se passe, retentera l'opération, obtiendra à nouveau l'erreur et se lassera.
À l'inverse, pour un utilisateur expérimenté et curieux, certaines erreurs pourraient révéler des informations sensibles sur votre serveur et ainsi exposer des vulnérabilités qu'il sera certainement en mesure exploiter (du moins, nous partirons toujours de la supposition qu'il en est capable).


Configuration

Pour un environnement de développement, il est conseillé d'utiliser :
display_errors = On
Pour un environnement en production, il est conseillé d'utiliser (à moins que le développeur souhaite pouvoir afficher ses propres messages, cf. la directive suivante) :
display_errors = Off

II-2. error_reporting

Cette directive permet de déterminer quelles erreurs seront affichées.
Voici ce que dit le fichier php.ini à ce sujet :
; E_ALL             - toutes les erreurs et tous les avertissements
; E_ERROR           - erreurs fatales au moment de l'exécution
; E_WARNING         - avertissements au moment de l'exécution (erreurs non fatales)
; E_PARSE           - erreurs de syntaxe au moment de la compilation
; E_NOTICE          - informations au moment de l'exécution (ce sont généralement
;   des avertissements résultant d'une erreur de programmation, mais il n'est pas exclu que
;   cela soit intentionnel : par exemple, utiliser une variable non initialisée et se reposer
;   sur le fait qu'elle soit initialisée automatiquement comme une chaîne vide)
; E_CORE_ERROR      - erreurs fatales qui ont lieu au moment du démarrage initial de PHP
; E_CORE_WARNING    - avertissements (erreurs non fatales) qu ont lieu au moment du démarrage initial de PHP
; E_COMPILE_ERROR   - erreurs fatales de compilation
; E_COMPILE_WARNING - avertissements au moment de la compilation (erreurs non fatales)
; E_USER_ERROR      - message d'erreur généré par l'utilisateur
; E_USER_WARNING    - message d'avertissement généré par l'utilisateur
; E_USER_NOTICE     - message d'information généré par l'utilisateur

Dangers

À part risquer de montrer au monde entier que votre site est mal codé (mauvaise gestion d'erreurs)...
Sérieusement, pour un utilisateur expérimenté, cela peut lui indiquer comment il peut s'introduire dans votre application. Il est donc préférable d'adopter la technique de l'autruche et cacher ce que vous pouvez !


Configuration

S'il s'agit d'un serveur de développement ou bien si la directive display_errors est désactivée, nous pouvons tout afficher :
error_reporting = E_ALL
Dans les autres cas, il sera préférable de limiter l'affichage aux erreurs que le développeur souhaite afficher :
error_reporting = E_USER_ERROR & E_USER_WARNING & E_USER_NOTICE
Je le répète : il est impératif que la directive error_reporting soit activée à E_ALL pendant la phase de développement afin d'assurer un minimum de qualité dans vos applications.


Notes

En PHP, la fonction error_reporting() permet de modifier cette directive jusqu'à la fin de la durée de l'exécution d'un script.
<?php
error_reporting(E_ALL);
error_reporting(E_USER_ERROR & E_USER_WARNING & E_USER_NOTICE);
error_reporting(E_ALL & ~E_NOTICE);
?>

II-3. magic_quotes

Ces directives ont fait le succès de PHP en tant que Personal Homepage (c'est l'ancien nom de PHP), c'est-à-dire il y a bien longtemps, car elles simplifiaient la vie des développeurs.
Depuis, les temps ont changé. Les utilisateurs malicieux sont devenus plus sournois, les applications sont devenues plus complexes. L'ajout automatique de slashes n'est pas la solution à tous les problèmes. De plus, elle peut générer des comportements que nous n'avons pas prévus. Il y a tellement d'exemples de jeunes développeurs qui s'étonnent de voir des slashes dans leurs variables !
Les directives magic_quotes servent à échapper automatiquement certains caractères (comme l'apostrophe ' et les guillemets ") en les préfixant d'un antislash \.


Dangers

Le seul danger auquel je puisse penser est que le développeur fasse trop confiance à ces directives et qu'il ne vérifie pas les données lui-même quand c'est nécessaire.


Configuration

Quel que soit l'environnement d'exécution des scripts, il est recommandé de désactiver ces options car elles sont génériques (donc peu adaptées). De plus, il est probable qu'elles finissent par avoir des conséquences indésirables si vous oubliez d'annuler leur effet (présence d'antislashes \ dans votre base de données).
magic_quotes_gpc = Off
magic_quotes_runtime = Off
magic_quotes_sybase = Off

Notes

En PHP, plusieurs fonctions sont intimement liées à ces directives
  • get_magic_quotes_gpc() et get_magic_quotes_runtime() : Permettent de connaître la valeur des directives correspondantes.
  • addslashes() : Mime leur comportement S'il s'agit d'enregistrer des informations dans une base de données MySQL, il sera préférable d'utiliser mysql_real_escape_string() puisque cela permet de tenir compte de l'encodage des caractères du client.
  • stripslashes() : Annule leur comportement.

II-4. register_globals

Voici l'autre directive de configuration qui a fait le succès de l'ancien Personal Homepage. Tout comme pour les magic_quotes, il a été prouvé depuis bien longtemps que, mal gérée, cette directive peut créer plus de problèmes qu'elle n'en règle.

Cette option a permis à PHP de devenir très célèbre il y a quelques années car cela le code était simplifié par son activation. En contrepartie, les développeurs prenaient moins garde au contenu de leurs variables, ce qui a fait paraître de nombreux problèmes de sécurité d'applications Web (et la mauvaise réputation de PHP sur ce point, alors que l'entière faute revient aux développeurs -dont j'ai fait partie, comme beaucoup-).


Dangers

Un utilisateur peut faire appel à votre script en ajoutant ses propres paramètres. Cette directive permet de transformer ces paramètres en variables locales. Dans certaines situations, cela peut remplacer vos variables locales du même nom. Dans d'autres, cela peut permettre à un utilisateur de sauter un test effectué dans votre code et d'atteindre une partie du code qu'il n'aurait pas dû pouvoir atteindre.
En bref : cette directive, si activée, vous enlève une grosse partie du contrôle que vous avez de votre application.
Fichier test_globals.php :
<?php
if(isset($foo)){
    die('Rentré dans le if');
}
?>
Appelez cette page en ayant avec la directive register_globals mise à On (et après avoir redémarré votre serveur Web pour appliquer les changements).
Il ne se passe rien, puisque la $foo variable n'existe pas. Maintenant, appelez votre script en utilisant l'URL suivante : "test_globals.php?foo". Il n'y a même pas besoin de donner une valeur à la variable, il suffit de la mettre dans l'URL pour qu'elle soit créée. Résultat : nous rentrons dans le if alors que notre code est relativement correct ! Nous avions simplement supposé que la variable locale $foo ne pouvait que provenir de notre script, cela suffit pour qu'il possède une faille de sécurité.
J'ai donné ici du code inoffensif car je ne souhaite pas indiquer comment faire planter un site Web. Mon objectif était de démontrer le danger de cette directive register_globals : j'espère y être parvenu avec cet exemple simpliste.


Configuration

register_globals  =  Off

Notes

En PHP, la fonction ini_set() permet de modifier la configuration du serveur mais seulement si PHP est installé comme un module du serveur Apache. Je trouve que c'est bien peu fiable comme supposition. Se reposer sur sa disponibilité ne permet pas de développer des applications fiables ; par conséquent, il ne faut pas le faire.



Valid XHTML 1.1!Valid CSS!

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2006 Guillaume Rossolini. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.