Fixation de la Session PHP / détournement

j'essaie de comprendre plus au sujet de PHP fixation de Session et détournement et comment prévenir ces problèmes. J'ai lu les deux articles suivants sur le site de Chris Shiflett:

  • Fixation De La Session
  • Détournement De Session

cependant, je ne suis pas sûr de comprendre les choses correctement.

pour empêcher la fixation de la session suffit-il d'appeler session_regenerate_id(true); après avoir réussi à connecter quelqu'un? Je pense que je comprends bien.

il parle également de l'utilisation de tokens passés dans les urls via $_GET pour empêcher le détournement de session. Comment cela serait-il fait exactement? Je suppose que quand quelqu'un se connecte vous générez leur token & le stockez dans une variable de session, puis sur chaque page vous comparez cette variable de session avec la valeur de la $ _GET variable?

est-ce que ce token devrait être modifié une seule fois par session ou sur chaque page chargée?

est-ce aussi un bon moyen d'empêcher les détournements sans avoir à passer une valeur dans les urls? ce serait beaucoup plus facile.

140
demandé sur Scott Arciszewski 2011-02-22 19:37:11

5 réponses

Ok, il y a deux problèmes distincts mais liés, et chacun est traité différemment.

Fixation De Session

C'est là un attaquant définit explicitement l'identifiant de session d'une session pour un utilisateur. Typiquement en PHP C'est fait en leur donnant une url comme http://www.example.com/index...?session_name=sessionid . Une fois que l'attaquant donne l'url au client, l'attaque est la même qu'une attaque de détournement de session.

il y a plusieurs façons de prévenir fixation de la session (faites-les tous):

  • Set session.use_trans_sid = 0 dans votre fichier php.ini . Cela indiquera à PHP de ne pas inclure l'identifiant dans L'URL, et de ne pas lire L'URL pour les identificateurs.

  • Set session.use_only_cookies = 1 dans votre fichier php.ini . Cela indiquera à PHP de ne jamais utiliser D'URL avec des identificateurs de session.

  • régénérez l'ID de session à chaque fois que le statut de la session change. Cela signifie l'un des éléments suivants:

    • authentification de l'utilisateur
    • stocker des informations sensibles dans la session
    • changer quoi que ce soit à propos de la session
    • etc...

Détournement De Session

c'est là qu'un attaquant obtient une emprise d'un identifiant de session et est capable d'envoyer des demandes comme si elles étaient de cet utilisateur. Cela signifie que depuis que l'attaquant a l'identifiant, ils sont presque impossibles à distinguer de l'utilisateur valide en ce qui concerne le serveur.

vous ne pouvez pas empêcher directement le détournement de session. Vous pouvez cependant mettre suit en, il est très difficile et plus difficile à utiliser.

  • utilisez un identificateur de hachage de session fort: session.hash_function dans php.ini . Si PHP < 5.3, définissez session.hash_function = 1 pour SHA1. Si PHP > = 5.3, définissez-le à session.hash_function = sha256 ou session.hash_function = sha512 .

  • envoyer un hachage fort: session.hash_bits_per_character dans php.ini . Réglez ça sur session.hash_bits_per_character = 5 . Bien que cela ne rende pas plus difficile de se fissurer, Cela fait une différence quand l'attaquant essaie de deviner l'identifiant de session. Le code d'identification de la plus courte, mais utilise plus de caractères.

  • définit une entropie supplémentaire avec session.entropy_file et session.entropy_length dans votre fichier php.ini . Définissez le premier à session.entropy_file = /dev/urandom et le second au nombre d'octets qui seront lus à partir du fichier entropy, par exemple session.entropy_length = 256 .

  • changer le nom de la session du PHPSESSID par défaut. Pour ce faire, vous pouvez appeler session_name() avec votre propre identifiant comme premier paramètre avant d'appeler session_start .

  • Si vous êtes vraiment paranoïaque vous pouviez faire tourner le nom de la session, mais méfiez-vous que toutes les séances seront automatiquement invalidé si vous modifiez cette valeur (par exemple, si vous rendre dépendant du temps). Mais, selon votre cas d'utilisation, il peut être un option...

  • changez souvent votre identifiant de session. Je ne ferais pas cela chaque demande (à moins que vous vraiment besoin de ce niveau de sécurité), mais à un intervalle aléatoire. Vous voulez changer cela souvent, car si l'attaquant n'a détourner une session, vous ne voulez pas être en mesure de l'utiliser trop longtemps.

  • Inclure user agent $_SERVER['HTTP_USER_AGENT'] dans la session. Fondamentalement, quand la session commence, stockez-le dans quelque chose comme $_SESSION['user_agent'] . Ensuite, sur chaque requête subséquente, Vérifiez qu'elle correspond. Notez que cela peut être truqué de sorte qu'il n'est pas 100% fiable, mais il est préférable de ne pas.

  • Inclure adresse IP de l'utilisateur à partir de $_SERVER['REMOTE_ADDR'] dans la session. Essentiellement, lorsque la session commence, stocker dans quelque chose comme $_SESSION['remote_ip'] . Cela peut être problématique certains FSI qui utilisent plusieurs adresses IP pour leurs utilisateurs (comme AOL avait l'habitude de le faire). Mais si vous l'utilisez, il sera beaucoup plus sûr. La seule façon pour un attaquant de simuler l'adresse IP est de compromettre le réseau à un moment donné entre l'utilisateur réel et vous. Et s'ils compromettent le réseau, ils peuvent faire bien pire qu'un détournement (comme des attaques MITM, etc).

  • incluez un token dans la session et du côté des navigateurs que vous incrémentez et comparer souvent. Fondamentalement, pour chaque requête faire $_SESSION['counter']++ du côté du serveur. Aussi faire quelque chose dans JS sur le côté des navigateurs pour faire la même chose (en utilisant un stockage local). Ensuite, lorsque vous envoyez une requête, prenez simplement une nonce d'un jeton, et vérifiez que la nonce est la même sur le serveur. En faisant cela, vous devriez être en mesure de détecter une session détournée puisque l'attaquant n'aura pas le compteur exact, ou s'ils le font, vous aurez 2 systèmes transmettant le même nombre et pouvez dire que l'un est faux. Ce ne fonctionne pas pour toutes les applications, mais est une façon de combattre le problème.

Une note sur les deux

la différence entre la Fixation de la Session et le détournement ne concerne que la façon dont l'Identificateur de session est compromis. Dans la fixation, l'identifiant est défini à une valeur que l'attaquant connaît avant main. En détournant il est soit deviné ou volé à l'utilisateur. Sinon les effets des deux sont les mêmes, une fois l'identifiant est compromise.

Session ID Regeneration""

chaque fois que vous régénérez l'Identificateur de session en utilisant session_regenerate_id l'ancienne session doit être supprimée. Cela se produit de manière transparente avec le gestionnaire de session core. Cependant, certains manipulateurs de session personnalisés utilisant session_set_save_handler() ne font pas cela et sont ouverts à l'attaque sur les anciens identificateurs de session. Assurez-vous que si vous utilisez une séance personnalisée gestionnaire, vous de garder une trace de l'identifiant que vous ouvrez, et si c'est pas le même que celui que vous enregistrez explicitement supprimer (ou modifier) l'identificateur de l'ancien.

en utilisant le gestionnaire de session par défaut, vous pouvez simplement appeler session_regenerate_id(true) . Cela supprimera les anciennes informations de session pour vous. L'ancien ID n'est plus valide et sera la cause d'une nouvelle session est créée si l'attaquant (ou n'importe qui d'autre d'ailleurs) tente de l'utiliser. Soyez prudent avec les gestionnaires de session personnalisés....

destruction D'une Session

si vous voulez détruire une session (sur la déconnexion par exemple), assurez-vous de la détruire complètement. Cela inclut la désactivation du témoin. Utilisation session_destroy :

function destroySession() {
    $params = session_get_cookie_params();
    setcookie(session_name(), '', time() - 42000,
        $params["path"], $params["domain"],
        $params["secure"], $params["httponly"]
    );
    session_destroy();
}
209
répondu ircmaxell 2014-04-19 06:21:54

session attaques ont le même objectif: accéder à une légitime session d'un autre utilisateur. Mais les vecteurs d'attaque sont différents:

  • dans un fixation de Session attaque , l'attaquant a déjà accès à une session valide et tente de forcer la victime à utiliser cette session particulière.

  • Dans un Session Détourner attaquer , l'attaquant essaie d'obtenir l'identité de la session de la victime pour utiliser sa session.

dans les deux attaques, l'ID de session est les données sensibles sur lesquelles ces attaques sont focalisées. C'est donc L'ID de session qui doit être protégé à la fois pour un accès en lecture (détournement de Session) et un accès en écriture (Fixation de Session).

la règle générale de protection des données sensibles par L'utilisation de HTTPS s'applique dans ce cas, trop. En outre, vous devez faire ce qui suit:

pour prévenir Fixation de Session attaques, assurez-vous que:

pour prévenir détournement de Session attaques, assurez-vous que:

pour prévenir les deux attaques de session, assurez-vous que:

  • n'accepter que les sessions initiées par votre demande. Vous pouvez le faire en prenant les empreintes digitales d'une session sur l'initiation avec renseignements sur le client. Vous pouvez utiliser L'ID User-Agent mais n'utilisez pas l'adresse IP distante ou toute autre information qui pourrait changer d'une demande à l'autre.
  • pour changer l'ID de session en utilisant session_regenerate_id(true) après une tentative d'authentification ( true seulement sur le succès) ou un changement de privilèges et détruire l'ancienne session. (Assurez-vous de conserver tous les changements de $_SESSION en utilisant session_write_close avant régénérer L'ID si vous voulez conserver la session associée à l'ancien ID; sinon seule la session avec le nouvel ID sera affectée par ces changements.)
  • pour utiliser une bonne implémentation d'expiration de session (voir Comment puis-je expirer une session PHP après 30 minutes? ).
35
répondu Gumbo 2017-05-23 12:34:19

les jetons que vous mentionnez sont un" nonce " - nombre utilisé une fois. Ils ne doivent pas nécessairement être utilisés une seule fois, mais plus ils sont utilisés, plus les chances que le nonce peut être capturé et utilisé pour détourner la session.

un autre inconvénient de nonces est qu'il est très difficile de construire un système qui les utilise et permet plusieurs fenêtres parallèles sur la même forme. par exemple, l'utilisateur ouvre deux fenêtres sur un forum, et commence à travailler sur deux postes:

window 'A' loads first and gets nonce 'P'
window 'B' loads second and gets nonce 'Q'

si vous n'avez aucun moyen de suivre plusieurs fenêtres, vous n'aurez stocké qu'un seul nonce - celui de la fenêtre B/Q. Lorsque l'utilisateur soumet ensuite son message depuis la fenêtre A et passe en nonce 'P', le système de SAT rejettera le message comme P != Q .

6
répondu Marc B 2011-02-22 16:44:49

Je n'ai pas lu L'article de Shiflett, mais je pense que vous avez mal compris quelque chose.

par défaut PHP passe le token de session dans L'URL chaque fois que le client n'accepte pas les cookies. Oherwise dans le cas le plus courant, le token de session est stocké sous forme de cookie.

cela signifie que si vous mettez un token de session dans L'URL PHP le reconnaîtra et essaiera de l'utiliser par la suite. La fixation de Session se produit quand quelqu'un crée une session et puis astuces un autre utilisateur pour partager la même session en ouvrant une URL qui contient le token de session. Si l'utilisateur s'authentifie auprès d'une certaine façon, l'utilisateur malveillant sait alors le jeton de session d'un authentifié, qui pourrait avoir des privilèges différents.

comme je suis sûr que Shiflett explique, la chose habituelle à faire est de régénérer un token différent chaque fois que les privilèges d'un utilisateur changent.

2
répondu Andrea 2011-02-22 16:49:45

Oui vous pouvez empêcher la fixation de session en régénérant l'id de session une fois lors de la connexion. De cette façon, si l'attaquant ne connaît pas la valeur du cookie de la session nouvellement authentifiée. Une autre approche qui stoppe totalement le problème est définie session.use_only_cookies=True dans votre configuration d'exécution. Un attaquant ne peut pas définir la valeur d'un cookie dans le contexte d'un autre domaine. La fixation de la Session se base sur l'envoi de la valeur du cookie comme GET ou POST.

0
répondu rook 2011-02-22 17:02:49