La gestion de sessions est une des fonctionnalités indispensables à un site web professionnel. Cependant, la sécurité ici aussi est une contrainte forte afin d’éviter des désagréments aux utilisateurs finaux.
En effet, les sessions en PHP génèrent un identifiant unique (SID) qui est envoyé à l’utilisateur, de la forme 0D6441FEA4496C2. Une erreur commune est de penser que la simple génération d’un code unique et obscur suffit à sécuriser la chose. Malheureusement, le passage de cet identifiant au navigateur est la brèche dans le fort, car cette information peut se retrouver rapidement à des endroits inattendus.
- Si votre session est envoyée sous forme d’un cookie au navigateur, via un header Set-Cookie, le cookie est placé sur la machine de l’utilisateur et peut être facilement volé
- Si la session est passée en paramètre dans l’URL (transparent SID), il devient possible de récupérer le SID en navigant vers un nouveau site puisque l’URL de provenance est fournie à la nouvelle page (Referer).
On parle dans ce cas de vol de session puisqu’une personne mal intentionnée va utiliser l’identifiant de session et peut par exemple se retrouver avec les permissions d’un administrateur de site par exemple.
Il existe des précautions d’usage afin d’avoir des sessions bien sécurisées :
1. N’acceptez pas de sessions passées par GET/POST
Désactivez l’option dans php.ini nommée session.use_trans_sid. Ceci évite d’avoir des identifiants de session stockés dans l’URL et empêche donc tous les désagréments liés (bookmarks, historique du navigateur, URL de provenance…)
2. Régénérez l’identifiant de session à chaque requête
Utilisez la fonction session_regenerate_id() pour recréer à chaque chargement de page un nouvel identifiant afin de ne pas conserver le même SID durant toute la navigation de l’utilisateur. Ceci reste transparent pour l’utilisateur et ne lui réinitialise pas ses données côté serveur.
3. Pour aller un peu plus loin
Vous pouvez, après avoir implémenté les deux premiers points, ajouter des contrôles de cohérence sur votre session. Par exemple :
// On teste si la session est demandée depuis mon site if (strpos($_SERVER['HTTP_REFERER'], 'http://monsite') !== 0) session_destroy(); // Déconnexion par l'utilisateur if (isset($_GET['LOGOUT'])) session_destroy(); // On teste si l'IP ou le User Agent ont changé if ($_SERVER['REMOTE_ADDR'] !== $_SESSION['PREV_REMOTEADDR']) session_destroy(); if ($_SERVER['HTTP_USER_AGENT'] !== $_SESSION['PREV_USERAGENT']) session_destroy(); session_regenerate_id(); // Génération d'un nouvel identifiant // Ecriture du User Agent et de l'IP actuels $_SESSION['PREV_USERAGENT'] = $_SERVER['HTTP_USER_AGENT']; $_SESSION['PREV_REMOTEADDR'] = $_SERVER['REMOTE_ADDR'];
Commentaires récents