Question:
Quelqu'un peut-il fournir des références pour implémenter correctement les mécanismes de réinitialisation automatique du mot de passe des applications Web?
bdg
2011-01-28 04:39:03 UTC
view on stackexchange narkive permalink

Nous mettons en œuvre la réinitialisation automatique du mot de passe sur une application Web, et je sais comment je veux le faire (URL de réinitialisation du mot de passe limitée dans le temps par e-mail à l'adresse e-mail pré-enregistrée des utilisateurs).

Mon problème est que je ne trouve aucune référence pour indiquer aux développeurs d'utiliser cette technique. Quelqu'un peut-il me diriger vers de bonnes références sur cette technique?

Quel langage de programmation utilisez-vous?
Voir aussi une [question similaire] (http://stackoverflow.com/q/664673/10080) sur SO.
Voir: [Mot de passe oublié · OWASP Cheat Sheet Series] (https://cheatsheetseries.owasp.org/cheatsheets/Forgot_Password_Cheat_Sheet.html)
Huit réponses:
#1
+93
D.W.
2011-01-30 12:05:38 UTC
view on stackexchange narkive permalink

Quelques suggestions:

Ne réinitialisez pas le mot de passe de l'utilisateur avant d'être confirmé. Ne réinitialisez pas immédiatement le mot de passe de l'utilisateur. Ne le réinitialisez que lorsque l'utilisateur clique sur un lien de confirmation envoyé à son adresse e-mail pré-enregistrée.

Exiger un CAPTCHA. Lorsqu'un utilisateur demande que son mot de passe soit réinitialisé, forcez-le pour résoudre un CAPTCHA avant de continuer. Cela évite aux outils automatisés d'essayer de semer le chagrin de nombreux utilisateurs et l'oblige à prouver qu'il est un humain (pas un robot).

Aléatoire. La durée limitée L'URL de réinitialisation du mot de passe doit inclure un composant aléatoire et impossible à deviner. Assurez-vous d'utiliser un caractère aléatoire de qualité cryptographique. La sortie de / dev / urandom ou System.Security.Cryptography.RNGCryptoServiceProvider serait un bon choix. La sortie de rand () ou random () ou System.Random n'est pas assez aléatoire et serait un mauvais choix. Un GUID ou un horodatage n'est pas assez aléatoire et ne serait pas un bon choix.

Inclure une limite de temps. Le lien de confirmation de réinitialisation devrait expirer après un délai raisonnable: disons 24 heures . Le lien ne doit être utilisable qu'une seule fois et doit expirer immédiatement dès qu'il est utilisé.

Inclure un texte explicatif dans l'e-mail. Vous pouvez ajouter un texte explicatif au e-mail, pour expliquer pourquoi l'e-mail a été envoyé, au cas où quelqu'un demanderait une réinitialisation pour un compte qui n'est pas le vôtre. Vous pouvez inclure du texte comme "Quelqu'un a demandé que le mot de passe soit réinitialisé pour votre compte nom d'utilisateur sur site . Si vous avez fait cette demande, cliquez ici pour changer votre mot de passe. Si vous n'avez pas fait cette demande, cliquez ici pour annuler la demande. "

Envoyez un e-mail une fois le mot de passe réinitialisé. Une fois le mot de passe réinitialisé, envoyez un e-mail à l'utilisateur à faites-leur savoir que le mot de passe a été modifié. N'incluez pas le nouveau mot de passe dans cet e-mail.

Surveiller les annulations. Vous pouvez envisager d'inclure une logique pour surveiller la fréquence à laquelle les utilisateurs cliquent sur le lien d'annulation indiquant qu'ils n'ont pas demandé de réinitialisation. Si cela dépasse un certain seuil, il peut être utile d'envoyer une alerte aux opérateurs système. De plus, si un lien d'annulation pour une demande est visité après le lien de confirmation est visité, c'est une indication potentielle d'une attaque contre cet utilisateur - vous pouvez prendre des mesures à ce stade, par exemple, invalider le mot de passe de l'utilisateur et leur demander de réinitialiser à nouveau leur mot de passe. (Il s'agit d'une défense contre l'attaque suivante: l'attaquant accède à la boîte aux lettres de l'utilisateur, demande alors que son mot de passe sur votre site soit réinitialisé, puis visite le lien de confirmation. Si l'attaquant ne supprime pas ces e-mails de la boîte de réception de l'utilisateur, puis, lorsque l'utilisateur réel lit son e-mail, il peut cliquer sur le lien d'annulation, ce qui vous indique un problème éventuel.)

Utilisez HTTPS. Le lien doit utiliser https (et non http :), pour se protéger contre diverses attaques (par exemple, les attaques Firesheep sur les utilisateurs surfant sur le Web à partir d'un café Internet).

Consigner ces opérations. Je suggère de consigner toutes ces demandes. En plus de consigner le nom d'utilisateur de l'utilisateur, vous pouvez enregistrer l'adresse IP du client qui a demandé qu'un lien de réinitialisation soit envoyé par courrier électronique à l'utilisateur, ainsi que l'adresse IP du client qui a visité le lien de réinitialisation.

Lectures supplémentaires. Vous pouvez également lire l'excellent article de blog de Troy Hunt, Tout ce que vous avez toujours voulu savoir sur la création d'une fonction de réinitialisation de mot de passe sécurisée. Merci à @coryT pour un lien vers cette ressource.

Enfin, envisagez l'authentification sans mot de passe. Les mots de passe posent de nombreux problèmes en tant que mécanisme d'authentification, et vous pouvez envisager d'autres méthodes d'authentification des utilisateurs, telles que le stockage d'un cookie persistant sécurisé sur leur ordinateur avec un élément impossible à deviner secret pour les authentifier. De cette façon, il n'y a pas de mot de passe à oublier et aucun moyen pour l'utilisateur d'être hameçonné, bien que vous deviez fournir un moyen pour un utilisateur d'autoriser l'accès à partir d'une nouvelle machine ou d'un nouveau navigateur (éventuellement par e-mail au pré- adresse e-mail enregistrée). Ce document d'enquête contient une excellente étude de nombreuses méthodes d'authentification de secours et de leurs forces et faiblesses.

+1, notez également que bien qu'il soit populaire (comme en témoignent la plupart des mauvaises réponses [sur cette question SO] (http://stackoverflow.com/q/664673/10080)), un GUID n'est * pas * assez aléatoire . De plus, je voudrais simplement ajouter un mécanisme d'étranglement, c'est-à-dire qu'un utilisateur ne peut pas demander de réinitialiser son mot de passe, par exemple. 3000 fois en une heure.
Pour résumer ma conversation avec @avid à sa réponse à cette question, je dirais qu'un GUID de la version 4 est en effet principalement aléatoire, et [je suppose que c'est assez long] (http://security.stackexchange.com/questions/ 1952 / combien de temps devrait-un-aléatoire-nonce-be). Mais c'est probablement stupide et un peu dangereux à utiliser car il n'a pas été conçu à l'origine pour cette tâche. Et qui sait où votre code sera ensuite porté?
Il ne semble pas que "Si vous n'avez pas fait cette demande, cliquez ici pour annuler la demande." Serait nécessaire pour l'e-mail.
@nealmcb Voici un lien d'un gars de l'équipe du compilateur C # qui parle des GUID et qui mentionne très fortement que les GUID ne sont en aucun cas aléatoires cryptographiquement: http://blogs.msdn.com/b/ericlippert/archive/2012/05 /07/guid-guide-part-three.aspx - il y a eu une autre étude qui montre que les GUID Windows ne sont pas cryptographiquement aléatoires: http://www.gotdotnet.ru/blogs/denish/1965/ - Bottom Line: Don't utiliser des GUID à des fins cryptographiques :) (je ne sais pas si un système d'exploitation non Windows offre des garanties à cet égard, mais les Unices ont généralement à la fois / dev / random et / dev / urandom)
Combien de caractères la partie aléatoire doit-elle contenir?
"N'incluez pas le nouveau mot de passe dans cet e-mail." Si vous avez le mot de passe de l'utilisateur en texte clair, vous faites une erreur.
@DavidMurdoch, 64-80 bits devrait suffire pour la partie aléatoire. (40 bits seraient probablement suffisants à cet effet, mais pourquoi prendre des risques?)
AiliqjwhcfCMT See the link I posted above for more on D.W.'s answer (i.e. that a nonce of 64 bits is probably fine for this purpose): [How long should a random nonce be? - IT Security](http://security.stackexchange.com/questions/1952/how-long-should-a-random-nonce-be)
@MichaelStum Merci pour les liens, et comme je l'ai dit, c'est un mauvais choix. Mais en termes d'évaluation du risque réel, Google translate n'a pas beaucoup aidé avec ce message russe de Nikolay Denishchenko sur quelque chose comme "Device and cryptanalysis UUID-Generator for Windows". Pouvez-vous résumer les résultats en termes de nombre de bits d'entropie imprévisibles qu'il pense avoir dans les GUID de la version 4 de Windows et à quel point il serait difficile de les deviner à distance?
#2
+15
coryT
2012-07-20 02:11:58 UTC
view on stackexchange narkive permalink

Troy Hunt a un très bon article sur cette question exacte. Tout ce que vous avez toujours voulu savoir sur la création d'une fonction de réinitialisation de mot de passe sécurisée

Le blog de troy est une excellente ressource pour tout ce qui concerne la sécurité Web
#3
+9
Jesper Mortensen
2011-04-05 14:25:56 UTC
view on stackexchange narkive permalink

OK, donc votre question est la suivante: comment devez-vous structurer le processus de récupération de mot de passe / compte? Cela dépendra de ce que vous souhaitez optimiser: une expérience utilisateur sans tracas ou une bonne sécurité.

Si vous voulez une bonne sécurité:

  • Lors de l'inscription, l'utilisateur doit entrer son adresse e-mail.
  • Lors de l'inscription, l'utilisateur doit entrer un canal secondaire pour l'authentification - numéro de téléphone portable ou question de défi & réponse (c'est-à-dire " quoi le nom de jeune fille de votre mère "ou mieux).

  • Pendant la récupération, votre système obtient d'abord une vérification approximative de l'identité au moyen du canal secondaire ci-dessus - le défi question, ou en envoyant un code par SMS sur le téléphone mobile, ou similaire.

  • Lorsque le premier contrôle d'identité ci-dessus est effacé, le système envoie un e-mail de réinitialisation du mot de passe à l'adresse e-mail précédemment saisie uniquement . Il s'agit d'une mesure supplémentaire importante pour empêcher f.x. Exploits de type Sarah Palin.

  • L'e-mail ne doit pas contenir un nouveau mot de passe ou similaire. Il doit contenir un lien cliquable vers une page Web cryptée HTTPS sur votre site qui a) est liée au compte via une valeur secrète non-devinable fournie dans l'URL, b) est limité dans le temps, de sorte que la récupération du compte ne fonctionne que pendant x heures après sa demande, c) fournit un moyen pour l'utilisateur final de créer un nouveau mot de passe.

  • Ayez une bonne journalisation sur toutes les transactions de réinitialisation de compte, et demandez à un être humain de les surveiller et d'agir si elles semblent suspectes (regardez les journaux du serveur pour les adresses IP fx, faites de nombreuses demandes proviennent de la même adresse IP, existe-t-il des cas où un utilisateur tente de réinitialiser les mots de passe d'un pays différent de celui du propriétaire du compte enregistré, etc.).

Vous pouvez également contourner complètement cette complexité: Il est encore tôt, mais OAuth / OpenID / connexion via Facebook, Google, etc. supprime complètement cette complexité de vos systèmes, mais avec un peut-être convivialité moins bien établie.

Les questions de défi sont le contraire de la sécurité.
@DavidMurdoch: pouvez-vous fournir une référence qui traite de cela? J'aimerais en savoir plus.
@David Murdoch: Les questions de défi sont équivalentes à un mot de passe - mais la question clé est de savoir quoi. Dans mon schéma, ils débloquent un mécanisme de réinitialisation de mot de passe qui (vraisemblablement) * n'est pas sous le contrôle des attaquants *; l'adresse e-mail d'origine. Mais il est vrai que les mécanismes de réinitialisation de mot de passe échangent généralement une sécurité réduite pour une convivialité accrue, j'aurais peut-être dû le préciser plus clairement.
Notez qu'ici, dans le futur monde éblouissant de 2015, l'utilisation d'un numéro de téléphone dans le cadre d'un programme MFA s'est en quelque sorte effondrée, car le même petit appareil perdable sert de passerelle vers les e-mails et les SMS.
#4
+9
Rich Homolka
2012-07-23 22:18:52 UTC
view on stackexchange narkive permalink

N'importe quel endroit qui peut vous envoyer un mot de passe signifie qu'ils ne hachent pas le mot de passe, mais le stockent là où il est en quelque sorte déchiffrable en «texte clair». Ceci en soi est mauvais.

Probablement pas "le plus" sécurisé, mais plus sécurisé serait de:

Sur demande de mot de passe, envoyer un lien de réinitialisation de mot de passe à l'utilisateur avec GUID intégré. La session dans le GUID expire dans, hmm, heure environ.

Oui, pas de problème avec cela car j'ai une session protégée contre l'injection SQL, donc j'envoie un courrier avec un code de session de réinitialisation de mot de passe bien aléatoire et laisse une heure pour le changer, c'est OK.
@AndrewSmith - Vous devez autoriser l'utilisateur à sélectionner le nouveau mot de passe et non à lui envoyer, comme déjà expliqué, si vous êtes en mesure d'envoyer le mot de passe à l'utilisateur, il y a quelque chose de cassé dans votre modèle de sécurité.
Ce site Web génère actuellement un NOUVEAU mot de passe, l'envoie par e-mail, le hache et le stocke dans db, ce qui n'est pas bon je crois.
générer un mot de passe et ne pas l'expirer à la prochaine connexion est en effet une mauvaise idée.
If this GUID is in plain text, then it can be obtained with sql injection and then you are defeating the whole purpose of password hashing. This post is a dangerous suggestion by means of ambiguity.
Je devrais donc crypter un code de session de réinitialisation de mot de passe bien aléatoire et dans une fenêtre de 1h, permettre ensuite le changement - pas de problème.
#5
+6
Rory Alsop
2011-01-31 01:58:25 UTC
view on stackexchange narkive permalink

Une autre méthode qui peut ou non être appropriée pour votre application, mais qui est utilisée dans les applications bancaires en ligne et des types de choses similaires, consiste à envoyer la moitié du code de réinitialisation par SMS à un téléphone mobile enregistré. Du point de vue de l'attaquant, il s'agit d'un PITA complet car il nécessite le compromis de quelques canaux pour se briser.

#6
+6
Polynomial
2012-07-24 01:31:29 UTC
view on stackexchange narkive permalink

Le moyen le plus sûr d'effectuer une réinitialisation de mot de passe est de générer un grand jeton de réinitialisation unique aléatoire unique, avec une date d'expiration, liée à l'ID utilisateur. Le jeton doit être haché dans la base de données, car un attaquant disposant d'un accès SQL pourrait l'utiliser pour réinitialiser des mots de passe d'utilisateurs arbitraires.

Un lien de réinitialisation doit être envoyé à l'adresse e-mail, contenant le jeton de réinitialisation. Lorsque l'utilisateur clique sur le lien, le hachage du jeton doit être trouvé dans la base de données et la date d'expiration doit être vérifiée dans le futur. Si ces conditions sont remplies, l'utilisateur doit être présenté avec un écran qui lui permet de saisir un nouveau mot de passe.

L'ensemble de ce processus doit être effectué via SSL, sinon un attaquant peut renifler l'URL et réinitialiser le mot de passe avant que l'utilisateur ne le fasse.

Quelques autres conseils:

  1. Des questions secrètes, un inconvénient mineur pour les attaquants et un ennui majeur pour les utilisateurs. Évitez-les complètement.
  2. Présentez à l'utilisateur un défi de vérification humaine (par exemple un CAPTCHA) avant d'envoyer la réinitialisation du mot de passe. Cela empêche les demandes de réinitialisation automatique.
  3. Vérifiez si l'adresse IP effectuant la réinitialisation est celle qui s'est connectée avec succès au compte précédemment. Si ce n'est pas le cas, demandez plus de détails sur le compte / l'utilisateur, par exemple année de création du compte, date de naissance, première ligne d'adresse.
  4. Ajoutez un lien "Je n'ai pas demandé cet e-mail", afin que les utilisateurs puissent signaler des demandes de réinitialisation de mot de passe erronées.
  5. ol >
Même s'il est généré via SSL: vous n'avez aucune assurance que l'e-mail lui-même est transféré via SSL et cette méthode présente donc un énorme défaut de transit - le défaut de base du relais et de la récupération des e-mails.
@EvanCarroll "_la faille de base du relais e-mail et de la ** récupération ** ._" concernant la ** récupération des e-mails **: il est de la responsabilité de l'utilisateur d'utiliser une adresse e-mail de récupération d'un fournisseur de messagerie avec POPS, IMAPS ou Prise en charge de la messagerie Web HTTPS (et la plupart des fournisseurs de messagerie proposent les trois de nos jours).
@EvanCarroll Bien que ce ne soit pas une situation idéale, la sécurité est * toujours * secondaire à la convivialité. Si vous implémentez la connexion de navigateur la plus sécurisée au monde, mais qu'elle nécessite JavaScript, Flash, Java, ActiveX, Silverlight et un diplôme en informatique, vos utilisateurs s'éteindront. Le courrier électronique est la norme de facto pour ce type de fonctionnalité, principalement parce qu'il est utilisable par tout le monde. Le fardeau de la sécurité sur le système de messagerie et le réseau personnel d'un utilisateur n'est * pas * avec moi, ni ne devrait l'être.
AiliskljlnCMT if plausible deniability is your goal, then yes. If security is your goal, then no.
AiliagnmqtCMT "de-facto" standards have nothing to do with security. That's just an argument to maintain the status quo oblivious to the security implications.
AilikfkxbgCMT The argument for the status quo is that there is no acceptable alternative.
Je suis d'accord avec votre réponse, mais pourquoi incluriez-vous l'ID utilisateur dans le lien? Si, par exemple, cet identifiant d'utilisateur est un nombre à 8 caractères, ces 8 caractères sont tout aussi faciles à deviner, comme 8 caractères aléatoires supplémentaires dans votre jeton. Avec les caractères aléatoires, vous n'exposeriez pas l'ID utilisateur.
AiliuafsbbCMT True, but exposing the user ID isn't usually a big deal. You're likely to do it through the interface to your site anyway - look at StackExchange. Question 17542, answer 17547, your comment is 28508, you're user 8343, I'm user 5400, OP is user 10787. Trying to hide that info is difficult and would only introduce obscurity. In this case, though, the tokens should be unique, so the search should always return a single row regardless of whether the user ID is in the link.
#7
  0
frank
2011-04-06 10:36:01 UTC
view on stackexchange narkive permalink

Authentification à 2 facteurs par SMS! 1 vous connaissez le client et son numéro de portable, envoyez-leur un code unique à ajouter sur le site pour valider que c'est bien eux :)

Ce n'est pas nécessairement une solution à 2 facteurs, mais elle est hors bande.
Jusqu'à ce que quelqu'un vole son téléphone.
#8
  0
Andrzej Bobak
2012-07-24 19:28:06 UTC
view on stackexchange narkive permalink

Faites-en une procédure en quelques étapes. Par exemple, quelque chose comme ceci:

  1. L'utilisateur a oublié son mot de passe. Il clique sur le bouton «J'ai oublié mon mot de passe, envoyez-moi un e-mail que faire ensuite» (le libellé du bouton peut différer;))
  2. Votre serveur lui envoie un lien www.yourdomain.com/lostpassword?param_1 = x; param_2 = y
  3. Il clique sur le lien et est capable de se créer un nouveau mot de passe
  4. Il clique sur Soumettre. Tout est fait. Tout le monde est content

Un seul et unique piège est au point 3). Les valeurs X et Y doivent être aléatoires, imprévisibles et liées à ce compte particulier. Ils devraient également être à usage unique et devraient devenir obsolètes après une courte période (24 heures?). Stockez les deux valeurs dans une table dédiée avec les colonnes correspondantes:

  | some_id | user_id | X | Y | expire_time  

Si un utilisateur essaie d'utiliser le lien approprié, vérifiez si le délai d'expiration n'est pas respecté et sinon, permettez-lui de changer le mot de passe.

En quoi est-ce différent des autres réponses? Il n'y a aucun avantage à avoir à la fois X et Y, utilisez simplement une seule valeur aléatoire.
OK cool, but how it's secure agaist SQL Injection? Is it because of dedicated table?
@Polynominal une valeur est facile à briser via une attaque par force brute.
AiliwirxjkCMT you prevent yourself from an sql injection in a complete different way. It's how you filter user input and how you pass it to your queries.
@AndrzejBobak: Deux valeurs sont tout aussi faciles à percer par force brute qu'une valeur double de la longueur de l'une ou l'autre.


Ce Q&R a été automatiquement traduit de la langue anglaise.Le contenu original est disponible sur stackexchange, que nous remercions pour la licence cc by-sa 2.0 sous laquelle il est distribué.
Loading...