Benutzer vergessen Passwörter und (fast) alle Mitgliedschaftsseiten benötigen eine Möglichkeit, Benutzern zu helfen, wieder einzusteigen.
Ich möchte das gängige Szenario implementieren:
So plane ich, dies zu implementieren (C # / ASP.NET MVC):
member.ResetToken
) und sendet ihnen per E-Mail eine Verknüpfung mit dieser GUID E-Mail gesendet wird ihnen mitteilen, dass sie diesen Link nur einmal verwenden können) member.ResetToken
von der URL nach ihrem Konto. Wenn ihr Konto gefunden wird, zeigen Sie ihnen ein Passwort-Reset-Formular, und wenn sie das Zurücksetzen abgeschlossen haben, löscht sie das member.ResetToken
von ihrem Konto. Hier ist meine Frage: behalte es so (in der sie ihr Passwort mit diesem Link jederzeit, jetzt oder in der Zukunft zurücksetzen können) oder füge einen Zeitstempel hinzu, um zu begrenzen, wie lange sie ihr Passwort zurücksetzen müssen?
>Aus der UX-Perspektive ist die Möglichkeit, Ihr Passwort jederzeit zurückzusetzen, großartig, aber ich möchte sicherstellen, dass ich einige Sicherheitsprobleme nicht übersehen kann.
Ihr Schema funktioniert tatsächlich, aber es gibt einige Punkte, die verbessert werden könnten. Aber zuerst zu Ihrer ursprünglichen Frage nach dem Zeitlimit:
Lassen Sie uns die umgekehrte Frage stellen: Warum sollte ein Token infinit gültig bleiben?
Es hat keinen Vorteil, wenn der Reset-Link zwei Jahre später geklickt werden kann, klickt der Nutzer den Link in etwa einer Stunde an oder hat er den Link wahrscheinlich vergessen (und kann ggf. einen neuen anfordern). Auf der anderen Seite bedeutet das Lesen der E-Mails nicht zwangsläufig, dass ein Angreifer das E-Mail-Konto hacken muss, da ist beispielsweise der offene E-Mail-Client im Büro, ein verlorenes Handy, ein Backup auf dem (verlorenen) USB-Laufwerk ...
Die wichtigste Verbesserung ist, dass Sie nur einen Hash des Tokens in Ihrer Datenbank speichern sollten. Jemand mit Zugriff auf die Datenbank (SQL-Injection), könnte ansonsten für jede E-Mail-Adresse, die er mag, ein Passwort zurücksetzen, und weil er das neue Token sehen kann, könnte er damit sein eigenes Passwort setzen.
Dann würde ich diese Reset-Informationen in einer separaten Tabelle speichern. Dort können Sie die Benutzer-ID, das Hash-Token, ein Ablaufdatum und die Information, ob der Link bereits verwendet wurde, speichern. Der Benutzer befindet sich dann nicht in einem speziellen Status.
Vielleicht habe ich diesen Punkt missverstanden, aber der Reset-Link sollte auf eine spezielle Seite für das Zurücksetzen des Passworts zeigen. Wenn der Benutzer die Anmeldeseite aufruft, sollte keine besondere Behandlung erfolgen. Die Anmeldeseite sollte nicht wissen, dass ein Zurücksetzen des Kennworts aussteht.
Das Reset-Token sollte unvorhersehbar sein, dies kann am besten mit einem wirklich zufälligen Code erreicht werden, der aus der zufälligen Quelle des Betriebssystems liest.
Benutzer vergessen auch, Passwörter zurückzusetzen (Dinge passieren). Da ich über Passwörter paranoid bin, würde ich vorschlagen, die Lebensdauer der Verbindung auf 24 Stunden zu begrenzen. Das sollte mehr als genug sein. Es löst nicht das Problem des böswilligen Abfangens, aber es ist besser als nichts.
Es gibt also ein paar Probleme mit diesem Ansatz, denen ich mich in meinem Kommentar entziehen wollte. Wenn Sie das "Bestätigungs-Token" im Benutzer-Passwort speichern, haben Sie im Grunde nur das Passwort gelöscht.
Ich, eine böswillige Person, kann dann eine große riesige Liste von E-Mail-Adressen und ein Bot-Netz nehmen und Ihren Server mit Passwortzurücksetzungsanfragen überfluten und Ihre Benutzer von ihrem Konto ausschließen. Sicher, Ihre Benutzer erhalten eine E-Mail für das Zurücksetzen, aber wenn ich Passwörter schnell genug zurücksetzen kann, gibt es möglicherweise einen Rückstau von E-Mails (oder, wenn Sie es synchron tun, kann ich wahrscheinlich die gesamte Anwendung tun).
Ich, ein normaler Benutzer Ihres Systems, kann versuchen, mein Passwort zurückzusetzen, und kann nicht herausfinden, warum ich die Reset-E-Mail nicht bekomme, weil ich nicht einmal über einen Spam-Ordner weiß (oder nie angekommen ist) ). Glücklicherweise habe ich mich nur daran erinnert, was das Passwort war, aber es funktioniert nicht mehr, da das Passwort jetzt eine undurchsichtige GUID ist, und ich bin im Grunde tot im Wasser, bis ich die Reset-Email finden kann.
Hier ist der Prozess, den Sie verwenden sollten .
Auch, falls dies nicht bereits passiert, vergewissern Sie sich, dass Sie Hashing und Salting das Benutzerkennwort verwenden. Es klingt nicht so, als ob Sie das getan hätten, als Sie gerade das Passwort durch eine GUID ersetzt haben, also überprüfen Sie es einfach.
Ich würde folgende Vorschläge machen:
Erfordert einige Informationen, bevor der Benutzer auf die Schaltfläche "Passwort vergessen" klicken darf. Zum Beispiel benötigen Sie eine E-Mail-Adresse und ein Geburtsdatum.
Idealerweise sollte Ihre Benutzerschnittstelle keine Rückmeldung geben, die es einem Hacker ermöglicht, festzustellen, ob seine Rücksetzanforderung erfolgreich war. Sie möchten nicht, dass Ihre Seite für E-Mail-Adressen oder DOBs bearbeitet wird. Dies ist jedoch ein Kompromiss bei der Benutzerfreundlichkeit. Ob Sie dies tun, hängt davon ab, wie viel Sicherheit Sie wirklich benötigen.
Sie könnten auch in Betracht ziehen, ein Captcha zu benötigen, das Brute-Force- und DoS-Attacken erheblich erschwert.
Löse das einmalige Token so schnell wie möglich ab. Ein paar Stunden sind meiner Meinung nach genug. Sie sollten E-Mails niemals als privat betrachten - das ist es nicht, es sei denn, Sie verwenden eine sichere E-Mail-Technologie (z. B. PGP) zusätzlich zum Basisprotokoll (die meisten Leute nicht). Das Letzte, was Sie wollen, ist, dass sich ein Schwarzmarkt dort öffnet, wo Ihre GUIDs gekauft und verkauft werden. Genau das könnte passieren, wenn sie eine unendliche Lebensdauer haben.
Verwenden Sie keine GUIDs. Sie sind nicht kryptographisch zufällig und sind ratenswert. Ich schlage vor, Sie verwenden einen kryptografischen Zufallszahlengenerator und übersetzen ihn in base64.
Tags und Links security passwords password-recovery