Administrateur PHPfrance |
3131 Messages
03 mai 2009, 11:37
Il n'est pas utile de stocker la moindre info confidentielle dans les sessions. Tout ce qu'un pirate peut faire d'une session, c'est la voler pas la modifier (sauf accès au système de fichier du serveur, mais dans ce cas tout est déjà fini).
Donc pour marquer qu'un utilisateur est connecté,
stocker simplement son ID en session est largement suffisant, pas besoin d'en faire des tonnes avec des tokens & cie, ça ne sert à rien pour la partie session.
Concernant le
vol de session, c'est un risque qui n'est jamais nul. Pour résumer, il s'agit pour le pirate de voler le cookie de l'utilisateur, et de l'utiliser pour sa propre connexion. Côté serveur tu reçois le bon cookie, tu affectes donc la bonne session, et le pirate a ni vu ni connu pris la place de l'utilisateur honnête. Le voleur peut par exemple très facilement "scanner" un réseau Wifi mal protégé et intercepter les entêtes HTTP, qui contiennent les cookies (et hop, vol de session).
Il existe des pseudo-solutions, souvent basées sur l'adresse IP mais toutes apportent des désagréments (utilisateurs pour qui les sessions deviendront instables sur ton site) sans pour autant apporter une réelle solution puisqu'un pirate qui sait voler une session saura aussi très probablement faire de l'IP-spoofing (camoufler son adresse IP avec celle de son choix), voire carrément s'infiltrer sur le réseau de sa victime (toujours grâce aux Wifi mal protégés). Ma politique à ce sujet :
on ne peut rien faire d'efficace, donc autant ne pas s'emmerder à inventer des solutions moisies et laisser courir. Aux utilisateurs de savoir protéger leurs infos !
Il existe
une seule vraie solution qui consiste à protéger efficacement du scan d'entêtes HTTP (principale source de vol de sessions, le vol de fichier étant carrément anecdotique), c'est d'utiliser
HTTPS sur tout son site.
Ensuite, concernant l'identification automatique par cookie de type "remember me", la solution la plus simple et sécurisé c'est d'attacher en base de données à chaque compte une "clé d'identification automatique", et de stocker dans le cookie une clé qui sera par exemple le MD5 de login + clé d'identification (l'important étant que ce soit une encryption injective type MD5, SHA1, etc... et basé sur la clé + une information fixe propre à l'utilisateur qui sert de sel).
Mieux que de longs discours, un peu de pseudo-pseudo-code :
/////
// Identification par cookie (peut être placée au début de chaque page par exemple)
/////
if (!connecte()) // l'utilisateur n'est pas connecté
{
$cle = trouve_cle_identification(); // renvoie la valeur du cookie "remember me"
if ($cle) // il a le cookie
{
$utilisateur = select_utilisateur("MD5(CONCAT(username, authkey)) = '%cle%'", array('cle' => $cle)); // trouve l'utilisateur en fonction de cette clé
if ($utilisateur)
{
regenerer_cookie_identification(); // met à jour le champ "authkey" dans la base avec une chaine aléatoire de taille fixe, et met à jour le cookie correspondant
connecter($utilisateur); // connecte l'utilisateur en remplissant la session
}
else
{
supprimer_cookie_identification(); // supprimer le cookie d'authentification, vu qu'il est invalide
}
}
}
/////
// Réception du formulaire d'identification
/////
if (post('remember_me')) // l'utilisateur a coché "se souvenir de moi"
{
regenerer_cookie_identification();
}
[edit]Ajout du "else: supprimer_cookie_identification".[/edit]