PHP secure> date de dernière modification : 08/03/2006Le PHP est un langage moderne, puissant et, au regard de ses possiblités, relativement bien conçu du point de vue de la sécurité. Rappel des possibilités de PHP : interfaçage de bases de données, traitement de formulaires, lecture / écriture de fichiers, exécution de commandes système, ouverture / gestion de connexions réseaux, etc. Il est important de ne pas perdre de vue que les scripts sont exécutés côté serveur -- serveur web qui plus est, donc par définition aussi "exposé" que possible. Le but de cet article est de faire une synthèse des "bonnes pratiques", en matière de sécurité, dans l'écriture de scripts PHP. Ce document sera mis à jour aussi souvent que nécessaire, et profitera pleinement de vos remarques et suggestions. N'hésitez pas ! sommaire
pré-requisUne bonne connaissance (au mieux une bonne pratique) du PHP, des bases de données et du Web sont nécessaires à la bonne compréhension de cet article. Au besoin, on peut consulter mon ultra-concis PHP.Cela dit, le propos est ici d'être le plus clair, le plus généraliste, et, nous l'espérons, le plus didactique possible. Le lecteur est supposé également avoir lu la partie consacrée à la sécurité du manuel en ligne, que le présent article se propose de compléter. Enfin, il n'est peut-être pas inutile de rappeler que la sécurisation des scripts PHP ne saurait se substituer à la sécurisation du serveur sur lequel ils tournent ! D'excellents logiciels libres ont été conçus dans ce but (cf Sécuriser un réseau hétérogène avec des outils libres), n'hésitez pas à les mettre en œuvre... cgi ou sapi ?La compilation de PHP en tant que CGI (Common Gateway Interface) étant une pratique de plus en plus rare, nous redirigerons le lecteur vers la page du manuel consacré à ce sujet.Par ailleurs, un manuel des "bonnes pratiques" dans l'écriture des scripts CGI est disponible ici. Nous nous concentrerons donc ici sur l'utilisation, beaucoup plus répandue, de PHP installé en tant que module du serveur Web, ou SAPI (Server Application Programming Interface). principes de baseNon, la sécurité n'est pas (seulement) affaire de spécialistes. C'est l'affaire de tous, à tout instant, depuis la conception du projet, jusqu'à l'utilisation finale du programme et / ou service.Au-delà de la technique pure, en constante évolution, il s'agit d'acquérir les bonnes pratiques. L'ensemble de ces bonnes pratiques relève de la plus élémentaire prévention, sur laquelle on n'insistera jamais assez. Voici un florilège de principes essentiels à garder en mémoire en toute circonstance (liste non-exhaustive) :
le fichier php.iniQue vous installiez PHP vous-même ou que vous passiez par un hébergeur, la sécurisation de vos scripts dépend pour une grande part de la configuration du fichier php.ini.Voici les différentes options de configuration concernées : la faille include()Cette faille a fait l'objet d'une littérature abondante, grâce à quoi elle a pratiquement disparu aujourd'hui.Le but du jeu consiste à ne pas permettre à n'importe qui d'inclure n'importe quelle page, que ce soit pour accéder à des données sensibles, ou pour simplement défacer votre belle page d'accueil ;) Outre la désactivation de allow_url_fopen, qui interdira l'inclusion de fichiers distants, voici une manière très simple de se prémunir : <?php $filename = "./page.php"; if (file_exists($filename)) include($filename); ?> une excellente mesure consiste à regrouper les fichiers de bibliothèques dans un répertoire protégé par .htaccess.Il est également recommandé d'éviter de donner l'extension .inc aux fichiers à inclure. En effet, si le serveur n'est pas configuré pour interpréter les fichiers avec cette extension, il est tout bêtement possible de les télécharger ou, encore plus bêtement, que le code source s'affiche à l'écran... Pas terrible :( Cela dit, si vous avez accès à votre httpd.conf, il suffit de rajouter l'extension ".inc" ici : AddType application/x-httpd-php .phtml .pwml .php3 .php4 .php .php2 .incPas plus difficle que ça. autre solution : ajouter une seconde extension... par exemple ".php" :
<?php $filename .= ".php"; ?>> ou bien encore, toujours dans httpd.conf, interdire l'accès à de tels fichiers :
<Files ~ ".inc">
Order allow,deny
Deny from all
Satisfy All
</Files>
On le voit, les façons de se protéger sont multiples et variées. L'essentiel étant de comprendre, comme toujours, la nature du danger.les bases de donnéesDe même que sécuriser ses scripts n'a pas grand sens si le système ne l'est pas, il fortement conseillé de bien connaître son SGBD, particulièrement bien sûr ses mécanismes de sécurité.Le principal souci d'une bdd exposée sur le web provient des injections SQL évoquées plus haut. Sans rentrer dans des considérations avancées, rappelons seulement que le principe de ce type d'attaque est de passer des requêtes "imprévues" au SGBD, le plus souvent via les champs d'un formulaire, et grâce à l'emploi astucieux de caractères spéciaux ("'", "%", "*", "#", etc). un exemple très connu d'injection sql repose sur l'idée de "couper", à l'aide de commentaires, une partie de la requête à l'exécution.Soit un banal formulaire d'identification : <form method="post" action="auth.php"> login : <input type="text" name="login"><br /> password : <input type="password" name="password"><br /> <input type="submit" value="OK">> et une requête, encore plus banale, utilisant les variables issues du formulaire :
$query = "SELECT * FROM users WHERE login = '".$_POST['login'].
"' AND password = '".$_POST['password']."'";
Pour peu que le pirate connaisse un login "sensible" (sans en connaître le mot de passe), il pourrait essayer de renseigner ainsi le champ "login" du formulaire :
admin'#> notre requête deviendrait alors :
$query = "SELECT * FROM users WHERE login = 'admin'#'
AND password = 'jun40h'";
Ce qui a l'exécution donnerait le produit de la requête SQL suivante :
SELECT * FROM users WHERE login = 'admin'PHP ignorant tout ce qui se trouve après le signe '#' ne transmettra pas la dernière partie de la requête... Plus besoin de mots de passe ;) Pour vous prémunir contre ces désagréments, vous avez à votre disposition tout un arsenal de fonctions qui vous permettent de filtrer (ou "parser") les données transmises pas l'internaute. > il est également recommandé de hasher (via md5()) logins et mots de passe avant de les stocker. Exemple : <?php $login = trim(htmlspecialchars(addslashes($_SESSION['login']))); // parsing du login $password = trim(htmlspecialchars(addslashes($_SESSION['password']))); // parsing du password $query = "INSERT INTO clients VALUES (md5($login), md5($password))"; // insertion des variables hashées ?> à toute fin utile, rappelons qu'il est essentiel de créer un utilisateur de la base dont les droits seront restreints au strict minimum (lecture seule si possible).Si votre bdd contient des données réellement sensibles, le serveur doit être configuré pour supporter les connexions via SSL (Secure Socket Layer, www.openssl.org). les sessionsL'usage des sessions est un moyen sûr, simple, efficace et largement utilisé de "tracer" ses visiteurs (sites de commerce en ligne, forums, etc).Le principe en est simple : il s'agit d'attribuer un identifiant unique à chaque visiteur (par défaut PHPSESSID), ce qui créera un fichier dans un répertoire temporaire sur le serveur, fichier dans lequel seront stockées les variables générées par la session. Il suffit alors d'appeler (avant tout affichage html) la fonction session_start() sur chaque page où l'on souhaite utiliser ces variables. Cela peut se faire de différentes façons :
La première mesure élémentaire à prendre consiste à stocker logins et mots de passe dans une base de données (et au besoin relire la section précédente). une bonne idée est de récupérer (via la variable superglobale $_SERVER['REMOTE_ADDR']) l'ip du visiteur, afin de garantir son caractère unique :
<?php
if (isset($ip) && $ip == $_SERVER['REMOTE_ADDR']) {
echo "Welcome home, $login !";
}
else {
header('Location: login.php');
}
?>
référencesTen Security Checks for PHP : http://www.onlamp.com/pub/a/php/2003/03/20/php_security.htmlCreating a Secure PHP Login Script : http://www.devarticles.com/art/1/485 (Beaucoup) plus sur les injections SQL : L'injection (My)SQL via PHP Un tuto simple et bien construit sur la sécurité des applis Web : Secure your url © Thierry Lhomme, 2004. http://thierrylhomme.developpez.com/
Vos questions techniques : forum d'entraide PHP - Publiez vos articles, tutoriels et cours
et rejoignez-nous dans l'équipe de rédaction du club d'entraide des développeurs francophones Nous contacter - Hébergement - Participez - Copyright © 2000-2010 www.developpez.com - Legal informations. |