148 votes

PHP Session Fixation / Hijacking

J'essaie de comprendre plus au sujet de PHP Fixation de Session et le détournement et la façon de prévenir ces problèmes. J'ai lu les deux articles suivants sur Chris Shiflett site web:

Cependant, je ne suis pas sûr que je suis comprendre les choses correctement.

Pour aider à prévenir la fixation de session est-il suffisant pour appeler session_regenerate_id(true); après avoir connecté avec succès à quelqu'un? Je pense que je comprends bien.

Il parle aussi de l'aide de jetons transmis dans l'url via $_GET pour prévenir le détournement de session. Comment cela serait-il fait exactement? Je suppose que lorsque quelqu'un se connecte à vous de générer leur pion et le stocker dans une variable de session, puis sur chaque page, vous feriez comparer cette variable de session avec la valeur de $_GET variable?

Serait-ce jeton besoin d'être changé qu'une seule fois par session ou sur chaque chargement de la page?

Est aussi une bonne façon de prévenir le détournement sans avoir à passer une valeur dans l'url? ce serait beaucoup plus facile.

228voto

ircmaxell Points 74865

Ok, il y a deux distincts, mais liés à des problèmes, 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. Généralement en PHP c'est fait en leur donnant une url de la forme http://www.example.com/index...?session_name=sessionid. Une fois que l'attaquant donne l'url pour le client, l'attaque est le même comme un détournement de session d'attaque.

Il ya quelques façons de prévenir la fixation de session (faire tous les d'entre eux):

  • Ensemble session.use_trans_sid = 0 votre php.ini le fichier. Ceci va dire à PHP de ne pas inclure l'identifiant dans l'URL, et de ne pas lire les URL pour les identificateurs.

  • Ensemble session.use_only_cookies = 1 votre php.ini le fichier. Ceci va dire à PHP de ne jamais utiliser des Url avec des identifiants de session.

  • Régénérer l'ID de session à tout moment de la séance avec les changements d'état. Qu'entend de ce qui suit:

    • L'authentification de l'utilisateur
    • Le stockage d'informations sensibles dans la session
    • Changer quoi que ce soit à propos de la session
    • etc...

Détournement De Session

C'est là 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, puisque l'attaquant a l'identificateur, ils sont tous, mais impossible à distinguer de l'utilisateur valide par rapport au serveur.

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

  • Utilisez une forte session de hachage identifiant: session.hash_function en php.ini. Si PHP < 5.3, il session.hash_function = 1 pour SHA1. Si PHP >= 5.3, il session.hash_function = sha256 ou session.hash_function = sha512.

  • Envoyer une forte hash: session.hash_bits_per_character en php.ini. Réglez ce session.hash_bits_per_character = 5. Alors que ce n'en est pas plus difficile à craquer, il y a une différence lorsque l'attaquant essaie de deviner l'identifiant de session. L'ID sera plus courte, mais utilise plus de caractères.

  • Définir une entropie supplémentaire avec session.entropy_file et session.entropy_length votre php.ini le fichier. Définir les anciens d' session.entropy_file = /dev/urandom et le nombre d'octets qui seront lus à partir de l'entropie de fichier, par exemple session.entropy_length = 256.

  • Changer le nom de la session à partir de la valeur par défaut PHPSESSID. Ceci est accompli en appelant session_name() avec votre propre nom de l'identificateur en tant que 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 une option...

  • Faites pivoter votre identifiant de session souvent. Je ne ferais pas ça à 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 l' agent utilisateur à partir d' $_SERVER['HTTP_USER_AGENT'] à la session. En gros, quand la séance commence, de le stocker dans quelque chose comme $_SESSION['user_agent']. Ensuite, sur chaque demande ultérieure, vérifiez qu'il correspond. Notez que cela peut être faux il n'est donc pas fiable à 100%, mais c'est mieux que pas de.

  • Inclure l' adresse IP de l'utilisateur à partir d' $_SERVER['REMOTE_ADDR'] à la session. En gros, quand la séance commence, de le stocker dans quelque chose comme $_SESSION['remote_ip']. Cela peut être problématique à partir de certains fournisseurs d'accès que d'utiliser plusieurs adresses IP pour leurs utilisateurs (tels que AOL). Mais si vous l'utilisez, il sera beaucoup plus sûr. La seule façon pour un attaquant de faux à l'adresse IP est de compromettre le réseau à un moment donné entre le réel de l'utilisateur et de vous. Et si elles risquent de compromettre le réseau, ils peuvent faire bien pire que d'un détournement d'avion (comme les attaques de type MITM, etc).

  • Inclure un jeton dans la session et sur les navigateurs que vous incrémentation et de comparer les souvent. En gros, pour chaque requête n' $_SESSION['counter']++ sur le côté serveur. Aussi faire quelque chose en JS sur les navigateurs côté à faire de même (à l'aide d'un local de stockage). Ensuite, lorsque vous envoyez une demande, il suffit de prendre un nonce d'un jeton, et vérifier que le nonce est le même sur le serveur. En faisant cela, vous devriez être en mesure de détecter une détourné session étant donné que l'attaquant n'aura pas l'exact contre, ou s'ils le font, vous aurez 2 systèmes de transmission le même chef d'accusation, et vous pouvez dire est forgée. Cela ne fonctionne pas pour toutes les applications, mais est une façon de lutter contre le problème.

Une note sur les deux

La différence entre la Fixation de Session et le Détournement est seulement sur la façon dont l'identifiant de session est compromise. Dans la fixation, l'identificateur est défini sur une valeur que l'attaquant sait avant de la main. Dans le Détournement, c'est soit l'aurez deviné ou de vol de la part de l'utilisateur. Sinon les effets des deux sont les mêmes, une fois l'identifiant est compromise.

ID de Session Régénération

Chaque fois que vous régénérer l'identifiant de session à l'aide de session_regenerate_id l'ancienne session devrait être supprimé. Ce qui se passe de façon transparente avec le noyau de gestionnaire de session. Cependant, certains les gestionnaires de session personnalisés à l'aide de session_set_save_handler() ne le faites pas et sont ouverts à l'attaque sur les anciens identifiants de session. Assurez-vous que si vous utilisez un gestionnaire de session personnalisé, que vous 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 êtes très bien avec tout le qualifiant session_regenerate_id(true). Qui va supprimer 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....

La destruction d'une Session

Si vous allez détruire une session (logout par exemple), assurez-vous de détruire de fond en comble. Cela inclut la suppression du cookie. À l'aide de session_destroy:

function destroySession() {
    $params = session_get_cookie_params();
    setcookie(session_name(), '', time() - 42000,
        $params["path"], $params["domain"],
        $params["secure"], $params["httponly"]
    );
    session_destroy();
}

37voto

Gumbo Points 279147

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 les deux attaques de l'ID de session est de la nature sensible des données, ces attaques sont concentrées sur. C'est donc l'ID de session, qui doit être protégé à la fois d'un accès en lecture (Détournement de Session) et d'un accès en écriture (Fixation de Session).

La règle générale de la protection des données sensibles à l'aide de HTTPS s'applique dans ce cas. En outre, vous devez effectuer les opérations suivantes:

Pour empêcher la Fixation de Session attaques, assurez-vous que:

Afin de prévenir le Détournement de Session attaques, assurez-vous que:

Pour éviter à la fois la session attaques, assurez-vous que:

  • pour n'accepter que les séances que votre application ont initiées. Vous pouvez le faire par l'empreinte d'une session sur l'initiation à l'information spécifique de client. Vous pouvez utiliser le User-Agent ID, mais ne pas utiliser l'adresse IP distante ou toute autre information qui pourrait changer à partir de entre les demandes.
  • pour modifier l'ID de session à l'aide de session_regenerate_id(true) après une tentative d'authentification (true seulement sur la réussite), ou un changement de privilèges et de détruire l'ancienne session. (Assurez-vous de stocker toutes les modifications de l' $_SESSION l'aide session_write_close avant la régénération de l'ID si vous voulez conservé la session associée à l'ancien ID; sinon seulement à la session, avec le nouvel ID seront touchés par ces changements.)
  • pour utiliser un bon d'expiration de session de mise en œuvre (voir Comment puis-je expirer une session PHP après 30 minutes?).

7voto

Marc B Points 195501

Les jetons que vous mentionnez sont un "nonce" - numéro utilisé une fois. Ils n'ont pas nécessairement à être utilisé qu'une seule fois, mais plus ils sont utilisés, plus les chances que le nonce peut être captée et utilisée pour détourner la session.

Un autre inconvénient des nonces, c'est qu'il est très difficile de construire un système qui les utilise et qui permet à plusieurs parallèle de windows sur le même formulaire. 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 suivi de plusieurs fenêtres, vous n'avez stocké un nonce - que de la fenêtre B/Q. Lorsque l'utilisateur soumet ensuite à leur poste de fenêtre et passe dans nonce 'P', ths système rejettera la poste en tant que P != Q.

2voto

Andrea Points 7050

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

Par défaut, PHP passe le jeton de session dans l'URL à chaque fois que le client n'accepte pas les cookies. Oherwise dans la plupart des cas, le jeton de session est stocké dans un cookie.

Cela signifie que si vous mettez un jeton de session dans l'URL, PHP va le reconnaître et essayer de l'utiliser par la suite. Fixation de Session se produit lorsque quelqu'un crée une session et puis des trucs d'un autre utilisateur de partager la même session par l'ouverture d'une URL qui contient le jeton 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, l'habituel chose à faire est de régénérer un autre jeton à chaque fois les privilèges d'un utilisateur de changer.

0voto

Rook Points 34698

Oui, vous pouvez empêcher la fixation de session en régénérant l'identifiant de session une fois lors de la connexion. De cette façon, si l'attaquant ne connaîtra pas la valeur du cookie de la session nouvellement authentifiée. Une autre approche qui empêche totalement le problème est de définir 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 session repose sur l'envoi de la valeur de cookie en tant que GET ou POST.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X