2010-08-20 3 views
8

J'utilise 2 variables dans le cookie (expiration de 7 jours) qui est l'identifiant de l'utilisateur et le hachage. Hash est le codage sha1 de l'agent utilisateur et de l'ID utilisateur. Dans ce cas, un pirate peut se connecter qui est le navigateur de cookie connu volé. Quel chemin dois-je suivre ou quelle pratique est la meilleure pour me souvenir des problèmes de sécurité?Meilleure pratique pour me souvenir de la fonctionnalité

+0

Connexes: http://stackoverflow.com/search?q=php+session+hijacking –

+0

Vous devriez réutiliser un cadre d'authentification existant chaque fois que cela est possible, car, en réalité, c'est complexe. Par exemple, jetez un oeil à https://github.com/delight-im/PHP-Auth – caw

Répondre

6

Alors que vous pouvez hacher un user_id et secret_key, toute personne qui intercepte ce cookie peut se connecter à votre application. En plus de cela, vous pouvez faire en sorte que vos cookies se souvenir de moi disparaissent très rapidement. Personne n'aime un cookie éventé.

Vous pouvez stocker l'horodatage de la dernière visite de chaque utilisateur dans votre base de données et dans le cookie. Chaque fois que vous lisez le cookie pour enregistrer l'utilisateur, vous vérifiez que les deux horodateurs correspondent. Si ce n'est pas le cas, refusez l'utilisateur. Si c'est le cas, mettez à jour les horodatages. En utilisant cette méthode, chaque fois que votre utilisateur revient sur votre site, tous les anciens cookies sont obsolètes. Un pirate qui a intercepté un cookie a maintenant un cookie périmé sans valeur car il ne connaît pas l'horodatage exact dans le cookie actuel. Bien sûr, le pirate peut utiliser un cookie frais autant qu'il veut jusqu'à ce que l'utilisateur se connectera de nouveau.

//check for cookie 
if(isset($_COOKIE['remember_me'])) { 
    // get hash and time stamp from cookie 
    $hash = substr($_COOKIE['remember_me'],0,40); 
    $last_visit = substr($_COOKIE['remember_me'],41); 

    // query your db with $hash and $last_visit 

    // if hash and time stamp match up 
     // log in 

     // store the current time stamp in a variable to use for both 
     $time = date("Y-m-d H:i:s"); 
     // update the time stamp in your cookie 
     $cookie = $pass . "-" . $time; 
     setcookie('remember_me', $cookie, time()+60*60*24*100, '/'); 
     // update the time_stamp in your database 
    else { 
     // remove the remember me cookie 
     setcookie('remember_me', '', time()-42000, '/') 
    } 

Cette méthode offre une petite quantité de sécurité, et devrait certainement être utilisé le long des méthodes secondaires proposées dans d'autres réponses . Une clé hachée doit être stockée dans le cookie. Un cookie «remember me» ne peut pas être parfaitement sécurisé, de sorte qu'un nouveau mot de passe devrait être requis pour tout accès supplémentaire à des données ou des fonctionnalités d'application hautement sensibles.

Je recommande également de nommer votre cookie autre chose que 'remember_me' pour le rendre un peu plus difficile à trouver. Bien que cela n'ajoute pas beaucoup de sécurité, le cas échéant, nommer votre cookie 'ht33424' prend juste le temps de le nommer 'remember_me' ou 'hack_me'.

+0

Désolé mais je ne pense pas que j'aime cette réponse, à moins que je ne comprenne mal la logique, cela dépend de l'utilisateur qui charge une nouvelle page avant que le pirate ait le temps de copier et d'exécuter la page de son côté. À la fin d'une véritable session d'utilisateurs, il y a une grande fenêtre pour le piratage, et même pendant une session, il ne devrait pas être trop difficile de glisser entre les chargements de pages. Cela créerait un comportement de page inhabituel pour l'utilisateur authentique. Renommer les noms de variables cookie est une sécurité à travers l'obscurité et une perte de temps. (Suite) –

+0

... C'est probablement une autre couche qui va aider, mais un pirate déterminé ne sera pas empêché par cela. En outre, il n'est pas 100% failsafe pour les raisons que j'ai mentionnées ci-dessus. Pour un accès sensible et potentiellement dommageable aux informations sensibles et aux fonctionnalités, je ne recommanderais pas cette méthode comme une solution 100% sécurisée, mais seulement une amélioration marginale. –

+0

Pour un hacker déterminé, aucune méthode n'est 100% failsafe. Comme vous l'avez dit, il ne s'agit que d'une couche de plus pour essayer de nous rapprocher de 100%. Ceci est destiné à être utilisé avec d'autres méthodes, dont beaucoup sont fournies dans d'autres réponses. Une clé hachée devrait certainement être stockée dans le cookie, et une nouvelle saisie de mot de passe devrait être requise pour un accès supplémentaire aux informations et fonctionnalités sensibles. – SomewhereThere

0

Personnellement, je crée un hachage aléatoire et le stocke dans une table "remember me". La table contient également l'agent utilisateur, l'ID utilisateur et l'adresse IP. Je vérifie les deux chaque fois que je me reconnecte l'utilisateur de la fonction remember-me. Et si l'utilisateur se déconnecte manuellement, je supprime simplement cette ligne de la table. Ensuite, s'ils se reconnectent, cela crée un nouveau hachage aléatoire. Il n'y a vraiment aucun moyen de combattre quelqu'un qui renifle des paquets avec un système de se souvenir de moi (à moins que vous n'utilisiez des cookies sécurisés avec le flag uniquement HTTPS). Utilisez donc une connexion sécurisée avec des cookies HTTPS uniquement. Si vous ne pouvez pas, alors au moins rendre le hachage aléatoire, donc s'il est découvert, vous pouvez au moins générer un nouveau hachage pour tuer ce login ...

+0

Vous voulez expliquer le -1? – ircmaxell

+0

N'était pas moi, mais je me méfie toujours de la mise en œuvre comme cela car il suppose que les variables telles que l'agent utilisateur et l'ip sont des constantes quand elles ne le sont pas souvent. Je ne définirais pas cela comme une solution, mais plus d'une solution de contournement –

+0

Assez juste. Mais en l'absence d'un cookie HTTPS, y a-t-il vraiment de meilleures façons de vérifier la source? – ircmaxell

0

Vous pouvez éventuellement utiliser des sessions pour stocker le statut de l'utilisateur. Mais la tenue d'une session si longtemps entraîne le même problème, lorsque l'identifiant de la session sera volé. Vous pouvez joindre des informations de cookie avec un autre navigateur ou une autre adresse IP, mais cela causerait un problème si l'utilisateur n'a pas d'adresse IP statique. De toute façon, il est plus sûr de conserver un identifiant de session que de mettre le mot de passe endodé sha1 de l'utilisateur dans les cookies.

+0

Heureusement, l'OP n'a pas du tout parlé de mot de passe :) Mais oui, un ID de session pourrait être utile ici. – Piskvor

+0

Les sessions longues sont presque toujours une mauvaise idée. Ils ouvrent la porte à des attaques DOS spécifiques car vous pouvez consommer une quantité non négligeable d'espace de stockage puisque PHP ne peut pas GC les sessions jusqu'à ce que le timelimit soit atteint. Il y a des cas où c'est nécessaire, mais pour la plupart ce n'est pas une bonne idée ... – ircmaxell

0

HMAC

que je fais habituellement de cette façon que je l'ai donc rien à stocker sur le côté serveur sur des bases de données ou similaire.

Vous devez générer une chaîne aléatoire qui devient votre "clé secrète" et que vous devez stocker sur le côté serveur (probablement dans un script phig config comme une constante) et vous ne devez jamais le dire à personne. Je vais appeler cette clé secrète SECRET_KEY.

Ensuite, votre cookie doit définir deux valeurs:

  • USER_ID: l'ID utilisateur de l'utilisateur qui se la connexion automatique
  • HASH: Un hachage cryptographique sécurisé de USER_ID et SECRET_KEY. Ainsi, par exemple, md5(USER_ID . "-" . SECRET_KEY). (Quelque chose de différent de md5, comme sha1 ou sha256 est préféré).

Votre cookie final pourrait donc être: USER_ID:HASH.

Ensuite, lorsque vous devez vérifier si un cookie est un véritable souvenir de moi cookies, vous devez le faire:

function isCookieGenuine($cookie_value) { 
    list($value, $hash) = explode(':', $cookie_value, 2); 

    if (md5($value . "-" . SECRET_KEY) == $hash) 
    return true; 
    else 
    return false; 
} 

Le point est que vous seul pouvez générer un hachage qui passe cette vérification parce que la hash a besoin non seulement du USER_ID mais aussi du SECRET_KEYqui est inconnu par quelqu'un d'autre que le serveur! :)

Comme il est indiqué dans les commentaires que vous pouvez le faire en utilisant la fonction hash_hmac en PHP> = 5.1.2: http://us.php.net/manual/en/function.hash-hmac.php

+1

Déréférencement trop mauvais de tableau ne fonctionne pas encore dans PHP (il est implémenté dans le tronc seulement). Vous pouvez donc faire 'list ($ value, $ hash) = explode (':', $ cookie_value, 2);'. Et il peut être préférable pour la sécurité si vous implémentez un "secret" différent pour chaque utilisateur (puisque alors une compromission unique d'un secret n'ouvre pas la porte à chaque utilisateur). Oh, et PHP a une fonction intégrée ['hash_hmac'] (http://us.php.net/manual/fr/function.hash-hmac.php) pour faire ça ... – ircmaxell

+0

@ircmaxell, + 1 pour ton commentaire (je commence à oublier ces choses ... je ne suis plus en train d'écrire php :)). J'intègre vos conseils. Je ne suis pas d'accord avec l'idée de créer des secrets différents pour chaque utilisateur. Bien que ce soit évidemment plus sûr, l'avantage est minime à mon avis dans ce cas. –

1

Vous pouvez simlply définir la date d'expiration comme maintenant plus une année sur le cookie, mais avez alors un champ de mot de passe d'entrée dans toutes les zones sensibles, un peu comme l'utilisation amazon utilise. Un cookie piraté autorisera l'accès, mais pour acheter ou modifier quelque chose de personnel, un mot de passe doit être saisi de nouveau. Le problème avec les tables 'remember me' est que si un hacker peut accéder à cette table, il peut créer et se connecter à autant de comptes qu'il le souhaite. Vous pouvez argumenter que cela renforce la sécurité d'une caractéristique de se souvenir de moi, mais il doit être pesé avec les risques de ramollissement des zones de sécurité du genou.

Questions connexes