Maison > Article > développement back-end > Sécurité PHP - Détournement de session
La méthode d'attaque la plus courante contre les sessions est le détournement de session. Il s'agit d'un terme général désignant tous les moyens qu'un attaquant peut utiliser pour accéder aux sessions d'autrui. La première étape de toutes ces méthodes consiste à obtenir un identifiant de session légitime pour prétendre être un utilisateur légitime. Il est donc très important de s'assurer que l'identifiant de session ne soit pas divulgué. Les connaissances sur l'exposition et l'épinglage de session décrites dans les sections précédentes peuvent vous aider à garantir que l'identifiant de session n'est connu que du serveur et des utilisateurs légitimes.
Le principe de défense en profondeur (voir chapitre 1) peut être appliqué aux sessions Lorsque l'identifiant de session est malheureusement connu d'un attaquant, certaines mesures de sécurité discrètes apporteront également une certaine protection. En tant que développeur soucieux de la sécurité, votre objectif devrait être de rendre le processus de déguisement susmentionné plus sophistiqué. N’oubliez pas que peu importe la taille de l’obstacle, votre application offrira une protection.
La clé pour rendre le processus de déguisement plus complexe est de renforcer la vérification. L'ID de session est la principale méthode d'authentification, mais vous pouvez le compléter avec d'autres données. Toutes les données que vous pouvez utiliser sont uniquement les données de chaque requête HTTP :
GET / HTTP/1.1 Host: example.org User-Agent: Firefox/1.0 Accept: text/html, image/png, image/jpeg, image/gif, */* Cookie: PHPSESSID=1234
Vous devez être conscient de la cohérence des demandes et considérer tout comportement incohérent comme suspect. Par exemple, bien que l'en-tête User-Agent (le type de navigateur qui a émis cette requête) soit facultatif, le navigateur qui émet l'en-tête ne modifie généralement pas sa valeur. Si vous avez un utilisateur avec un ID de session de 1234 qui a utilisé Mozilla après s'être connecté Le navigateur Firfox est soudainement passé à IE, ce qui est plus suspect. Par exemple, vous pouvez atténuer le risque en exigeant un mot de passe à ce moment-là. En même temps, en cas de fausse alarme, cela aura moins d'impact sur les utilisateurs légitimes. Vous pouvez utiliser le code suivant pour vérifier la cohérence User-Agent :
<?php session_start(); if (isset($_SESSION['HTTP_USER_AGENT'])) { if ($_SESSION['HTTP_USER_AGENT'] != md5($_SERVER['HTTP_USER_AGENT'])) { /* Prompt for password */ exit; } } else { $_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']); } ?>
J'ai observé que dans certaines versions des navigateurs IE, les informations d'en-tête Accept envoyées lorsqu'un utilisateur accède normalement à une page Web et actualise une page Web sont différentes, de sorte que l'en-tête Accept ne peut pas être utilisé pour déterminer la cohérence.
Il est en effet efficace de s'assurer que les informations d'en-tête User-Agent sont cohérentes, mais si l'identifiant de session est passé via un cookie (la méthode recommandée), il va de soi que si l'attaquant peut obtenir l'identifiant de session, il peut également obtenir d'autres en-têtes HTTP. Étant donné que l'exposition aux cookies est liée aux vulnérabilités du navigateur ou aux vulnérabilités de script intersite, la victime doit visiter le site Web de l'attaquant et exposer toutes les informations d'en-tête. Tout ce que l'attaquant a à faire est de reconstruire l'en-tête pour empêcher toute vérification de cohérence des informations d'en-tête.
Une meilleure approche consiste à transmettre une balise dans l'URL, ce qui peut être considéré comme une deuxième forme de validation (quoique plus faible). L'utilisation de cette méthode nécessite un certain travail de programmation et il n'existe pas de fonction correspondante en PHP. Par exemple, en supposant que le jeton soit stocké dans $token, vous devez l'inclure dans tous les liens internes de votre application :
<?php $url = array(); $html = array(); $url['token'] = rawurlencode($token); $html['token'] = htmlentities($url['token'], ENT_QUOTES, 'UTF-8'); ?> <a href="index.php?token=<?php echo $html['token']; ?>">Click Here</a>
Pour faciliter la gestion de ce processus de livraison, vous pouvez placer l'intégralité de la chaîne de requête dans une variable. Vous pouvez ajouter cette variable à tous les liens afin que même si vous n'utilisez pas cette technique au départ, vous puissiez toujours facilement modifier votre code ultérieurement.
La balise doit contenir un contenu imprévisible, même si l'attaquant connaît tous les en-têtes HTTP envoyés par le navigateur de la victime. Une façon consiste à générer une chaîne aléatoire sous forme de balise :
<?php $string = $_SERVER['HTTP_USER_AGENT']; $string .= 'SHIFLETT'; $token = md5($string); $_SESSION['token'] = $token; ?>
Lorsque vous utilisez une chaîne aléatoire (telle que SHIFLETT), il est irréaliste de la prédire. À ce stade, capturer la balise sera plus pratique que prédire la balise. En transmettant la balise dans l'URL et en transmettant l'ID de session dans le cookie, l'attaque doit capturer les deux en même temps. Sauf si l'attaquant peut visualiser les informations brutes de toutes les requêtes HTTP envoyées par la victime à votre application, car dans ce cas, tout est exposé. Cette attaque est très difficile à mettre en œuvre (et donc rare), et sa prévention nécessite l'utilisation de SSL.
有专家警告不要依赖于检查User-Agent的一致性。这是因为服务器群集中的HTTP代理服务器会对User-Agent进行编辑,而本群集中的多个代理服务器在编辑该值时可能会不一致。
如果你不希望依赖于检查User-Agent的一致性。你可以生成一个随机的标记:
<?php $token = md5(uniqid(rand(), TRUE)); $_SESSION['token'] = $token; ?>
这一方法的安全性虽然是弱一些,但它更可靠。上面的两个方法都对防止会话劫持提供了强有力的手段。你需要做的是在安全性和可靠性之间作出平衡。
以上就是PHP安全-会话劫持的内容,更多相关内容请关注PHP中文网(www.php.cn)!