Il n'existe aucun moyen d'empêcher à 100% le détournement de session, mais certaines approches permettent de réduire le temps nécessaire à un attaquant pour détourner la session.
Méthode pour empêcher le détournement de session :
1 - toujours utiliser une session avec un certificat ssl ;
2 - envoyer le cookie de session uniquement avec httponly réglé sur true (empêcher javascript d'accéder au cookie de session)
2 - utilisez l'id de régénération de session à la connexion et à la déconnexion (note : n'utilisez pas la régénération de session à chaque requête car si vous avez des requêtes ajax consécutives, vous avez une chance de créer plusieurs sessions).
3 - définir un délai d'attente pour la session
4 - stocker l'agent utilisateur du navigateur dans une variable $_SESSION et comparer avec $_SERVER['HTTP_USER_AGENT'] à chaque requête
5 - Définissez un cookie symbolique et fixez le temps d'expiration de ce cookie à 0 (jusqu'à ce que le navigateur soit fermé). Régénérez la valeur du cookie pour chaque requête (pour les requêtes ajax, ne régénérez pas le cookie à jeton). EX :
//set a token cookie if one not exist
if(!isset($_COOKIE['user_token'])){
//generate a random string for cookie value
$cookie_token = bin2hex(mcrypt_create_iv('16' , MCRYPT_DEV_URANDOM));
//set a session variable with that random string
$_SESSION['user_token'] = $cookie_token;
//set cookie with rand value
setcookie('user_token', $cookie_token , 0 , '/' , 'donategame.com' , true , true);
}
//set a sesison variable with request of www.example.com
if(!isset($_SESSION['request'])){
$_SESSION['request'] = -1;
}
//increment $_SESSION['request'] with 1 for each request at www.example.com
$_SESSION['request']++;
//verify if $_SESSION['user_token'] it's equal with $_COOKIE['user_token'] only for $_SESSION['request'] > 0
if($_SESSION['request'] > 0){
// if it's equal then regenerete value of token cookie if not then destroy_session
if($_SESSION['user_token'] === $_COOKIE['user_token']){
$cookie_token = bin2hex(mcrypt_create_iv('16' , MCRYPT_DEV_URANDOM));
$_SESSION['user_token'] = $cookie_token;
setcookie('user_token', $cookie_token , 0 , '/' , 'donategame.com' , true , true);
}else{
//code for session_destroy
}
}
//prevent session hijaking with browser user agent
if(!isset($_SESSION['user_agent'])){
$_SESSION['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
}
if($_SESSION['user_agent'] != $_SERVER['HTTP_USER_AGENT']){
die('session hijaking - user agent');
}
note : ne pas régénérer le cookie token avec une requête ajax note : le code ci-dessus est un exemple. note : si les utilisateurs se déconnectent, le cookie token doit être détruit ainsi que la session.
6 - ce n'est pas une bonne approche d'utiliser l'ip de l'utilisateur pour empêcher le détournement de session parce que l'ip de certains utilisateurs change à chaque demande. QUI AFFECTENT LES UTILISATEURS VALIDES
7 - Personnellement, je stocke les données de session dans la base de données, mais c'est à vous de choisir la méthode que vous adopterez.
Si vous trouvez une erreur dans mon approche, veuillez me corriger. Si vous avez d'autres moyens d'empêcher l'hyjaking de session, dites-le moi.