Frage:
Wo soll ich beim Zurücksetzen des Passworts einen Benutzernamen speichern?
Sam
2020-06-21 22:45:56 UTC
view on stackexchange narkive permalink

Ich bin neu in der Webentwicklung und versuche, eine Funktion zum Zurücksetzen von Passwörtern gemäß den OWASP Spickzettel zu implementieren: Passwort-Spickzettel vergessen

Im Spickzettel wird empfohlen, den Benutzernamen nicht als Parameter zu senden, wenn das Formular gesendet und an den Server gesendet wird. Stattdessen sollte man es in der serverseitigen Sitzung speichern.

Ich bin mir jedoch nicht sicher, wie ich das tun soll, da der Benutzer dies tun muss, damit ich den Benutzernamen so speichern kann Geben Sie seinen Benutzernamen ein und senden Sie ihn irgendwann an den Server, oder? Warum senden Sie es nicht zusammen mit dem Formular, in dem der Benutzer Sicherheitsfragen beantwortet? Oder verstehe ich das nur falsch?

Vielleicht werde ich blind, aber ich kann die Empfehlung nicht finden, den Benutzernamen nicht als Parameter in die von Ihnen verlinkte Seite aufzunehmen.Könnten Sie den Satz zitieren, auf den Sie sich beziehen?
Um nur auf das Offensichtliche hinzuweisen: Sie dürfen nicht zulassen, dass der Benutzer den Benutzernamen zusammen mit der Anforderung zum Ändern / Zurücksetzen des Kennworts angibt, um zu verhindern, dass Benutzer Konten übernehmen, die sie versehentlich (oder durch intelligente Vermutungen) über die E-Mail-Adresse erfahren haben - auf diese Weise können sie dies einfach tun"IHR" Konto zurücksetzen, sonst niemand ... Abhängig davon, wie komplex Ihre Prüfung ist - Sie haben vermutlich eine Anfrage zum Zurücksetzen des Passworts für einen vorhandenen Benutzernamen (den Sie mithilfe Ihres Systems gelernt haben) und Ihre E-Mail-Adresse gesendet - sind beide vorhanden und bam .. Sie haben ein anderes Benutzerkonto erfasst
Sieben antworten:
ThoriumBR
2020-06-21 22:54:05 UTC
view on stackexchange narkive permalink

Dies ist, was ich normalerweise mache:

  1. Der Benutzer fragt nach einem Zurücksetzen des Passworts.

  2. Das System fragt nach dem registrierte E-Mail.

  3. Der Benutzer gibt eine E-Mail ein. Unabhängig davon, ob eine E-Mail vorhanden ist oder nicht, geben Sie an, dass Sie einen Rücksetzlink gesendet haben.

  4. Der Server speichert E-Mail-, Ablauf- und Reset-Token in einer reset_password -Tabelle

  5. Wenn auf den Link zugegriffen wird, wird der Ablauf überprüft und ein Formular erstellt Das Zurücksetzen des Passworts wird angezeigt.

  6. ol>

    Der Benutzer erhält nur einen Link mit einem großen zufälligen Token.

ok, vielen Dank!Ich werde das dann versuchen.Wissen Sie, warum das Senden des Benutzernamens mit dem Formular während der Rücksetzanforderung als unsicher angesehen wird?
Dies liegt daran, dass ein Benutzer möglicherweise den Benutzernamen in der Anforderung ändert und einen Rücksetzlink für einen anderen Benutzer erstellt.
Es gibt (offensichtlich) viele Debatten um Punkt "3.".Ein Angreifer kann einfach versuchen, sich mit der angegebenen E-Mail-Adresse zu registrieren und zu überprüfen, ob ein solches Konto vorhanden ist.Ich würde es einfach generisch halten und sagen "Benutzer gibt E-Mail ein", nicht mehr und nicht weniger.
Daumen hoch für * "und egal ob E-Mail existiert oder nicht, Sie sagen, dass Sie einen Reset-Link gesendet haben" *. Es ist ein so großer Angriffsvektor, und viele Milliarden-Dollar-Unternehmen erkennen ihn nicht.
Eine gute Verbesserung der Benutzerfreundlichkeit auf 3, ohne die Sicherheit zu beeinträchtigen, besteht darin, eine E-Mail mit dem Titel "Sie scheinen kein Konto zu haben ... Hier anmelden (Link)" zu senden, wenn für die eingegebene E-Mail kein Konto vorhanden ist (aber immer noch dasselbe ").hat eine E-Mail zum Zurücksetzen des Passworts gesendet (Nachricht auf dem Formular zum Anfordern des Zurücksetzens des Passworts).
@dmuensterer Ich würde es nicht als "großen" Angriffsvektor bezeichnen.Oft können Sie herausfinden, ob eine bestimmte E-Mail registriert ist oder nicht, indem Sie einfach versuchen, sich mit der E-Mail zu registrieren: Sie können sich nicht registrieren, wenn die E-Mail bereits registriert ist.Daher sind mehrdeutige Antworten auf das Zurücksetzen von Kennwörtern kein Knaller, um Informationen zu verbergen, aber sie können den Endbenutzern viel Verwirrung stiften.Ich persönlich füge diesen Schritt in meine eigenen Systeme ein, aber es ist nicht verrückt nach Systemen, die sich dagegen entscheiden.
3 ist ein Albtraum, da ich normalerweise auf Websites zurücksetze, von denen ich keine Ahnung habe, mit welcher der 7 E-Mails ich mich vor 10 Jahren registriert habe.
Ich stehe auf der Seite der Nutzlosigkeit, den Registrierungsstatus zu verbergen.Wenn Sie sich nicht mehrmals mit derselben E-Mail-Adresse registrieren können (was ich in einem vernünftigen System für unwahrscheinlich halte), ist der Versuch, sich zu registrieren, so schnell wie der Versuch, ihn zurückzusetzen. Es ist also kein wirklicher Vorteil, wenn Sie nicht sagen, dass Sie hier nicht registriert sind.
Es geht nicht unbedingt darum, die Tatsache zu verbergen, dass die E-Mail bereits registriert ist, sondern darum, die Gültigkeit des Paares aus Benutzername und E-Mail zu verbergen.Wenn Sie beim Zurücksetzen die gleiche Ratenbegrenzung, Captcha oder was auch immer haben wie bei der Registrierung, sagen Sie sicher, dass die E-Mail vom System global unbekannt ist, aber niemals, dass die E-Mail nicht mit dem Benutzernamen übereinstimmt (oder etwas allgemeineres, das Sie könnenÜbereinstimmung durch Seitenkanäle).
Punkt 3 ist sinnvoll für Systeme, auf denen Benutzer von einem Administrator erstellt werden.Für Systeme, in denen sich Benutzer frei registrieren können und E-Mail-Adressen als eindeutige Benutzernamen verwendet werden, ist Punkt 3 sinnlos, kein Wortspiel beabsichtigt.
@Ginnungagap: Warum sollten Sie auf der Seite zum Zurücksetzen des Passworts sowohl den Benutzernamen * als auch die E-Mail-Adresse eingeben?
Sie würden aber vermutlich nicht die Rücksetzseite erreichen, nachdem Sie den Benutzernamen angegeben haben (dh Anmeldung fehlgeschlagen, klicken Sie auf Passwort zurücksetzen, der Benutzername kann auf irgendeine Weise gespeichert werden).Ich sage nicht, dass es eine gute Idee ist. Ich sage, wenn Sie das tun, geben Sie keine Informationen über die richtige Zuordnung von Benutzername und E-Mail an, was noch schlimmer wäre.
Andererseits bin ich kein großer Fan davon, zu sagen, dass die E-Mail bereits im Anmeldeformular registriert ist, anstatt eine E-Mail zu senden, dass sie bereits ein Konto haben, das die Tatsache nicht der Außenwelt zugänglich macht.Angenommen, die E-Mail zum Zurücksetzen wurde trotzdem gesendet, da Sie ansonsten mehr Informationen als im Anmeldeforum verlieren.
multithr3at3d
2020-06-21 23:29:10 UTC
view on stackexchange narkive permalink

Sie sollten dem Client nicht vertrauen. Wenn der Client also in der Phase, in der das neue Passwort eingegeben wird, seinen Benutzernamen senden kann, was passiert, wenn er den Benutzernamen in den eines anderen ändert? Sie können das Konto eines anderen Benutzers zurücksetzen und das Konto übernehmen.

Die Antwort von @ ThoriumBR ist natürlich richtig. Eine andere Möglichkeit besteht darin, keinen Status auf dem Server zu speichern und alle im Reset-Link enthaltenen Informationen wie Benutzername und Ablaufzeit zu codieren. Dies kann sicher erfolgen, indem die Informationen mit HMAC oder ähnlichem kryptografisch signiert werden. Es gibt wahrscheinlich Bibliotheken für Ihre Sprache, die damit umgehen können, z. B. itsdangerous für Python.

Das Problem bei der Übernahme eines anderen Benutzerkontos besteht nur, wenn Sie den Benutzer sowohl den Benutzernamen als auch das Kennwort auswählen lassen.Wenn Sie nur eine E-Mail oder einen Benutzernamen verwenden (und die E-Mail dann an die registrierte E-Mail-Adresse des Benutzers senden), wird dies in beiden Fällen vermieden, nein?
@FrankHopkins Ich spreche über, nachdem der Reset-Link empfangen wurde
Ah, klar, das macht Sinn.Ich war mir nicht sicher, welchen Schritt OP mit ihrer Frage im Allgemeinen bedeutete.Aber als Verbesserungsvorschlag für die Antwort dann: Weisen Sie vielleicht darauf hin, dass Sie den gleichen Moment in dem Prozess meinen, in dem sie ihr neues Passwort in derselben Anfrage senden.
Pedro
2020-06-22 18:44:09 UTC
view on stackexchange narkive permalink

Um die hervorragende Antwort von ThoriumBR zu ergänzen:

  • Benutzer fragt nach einem Zurücksetzen des Passworts
  • System fragt nach der registrierten E-Mail
  • Benutzer gibt E-Mail ein, und unabhängig davon, ob E-Mail vorhanden ist oder nicht, sagen Sie, dass Sie einen Rücksetzlink gesendet haben, das Kennwort jedoch noch nicht zurückgesetzt haben.
  • Server speichert E-Mail, Ablauf und Reset-Token in einer reset_password -Tabelle
  • , wenn auf den Link zugegriffen wird…
    • Server überprüft den Ablauf des Reset-Tokens
    • Überprüft, ob es nicht verwendet wurde, bevor ,
    • der Benutzer zusätzliche Authentifizierungstoken eingeben muss. Dies kann 2FA, SMS-Code, Antwort auf voreingestellte Sicherheitsfragen usw. sein. und Schließlich
    • öffnet ein Formular zum Zurücksetzen des Kennworts.
    • Danach sollte der Benutzer in einem "abgemeldeten" Zustand belassen werden, in dem er sich mit dem neuen anmelden müsste Kennwort für den Zugriff auf die Anwendung.
  • Zusätzlich überprüft der Server, ob der Reset-Link nur für verwendet wurde ce innerhalb der Ablaufzeit

Der Benutzer erhält nur einen Link mit einem großen zufälligen Token.

Sollten Sie nicht auch andere vorhandene Sitzungen abmelden?
Ja, das wäre klug, nachdem sich der Benutzer mit alternativen Authentifizierungsfaktoren authentifiziert hat.
mentallurg
2020-06-22 02:54:52 UTC
view on stackexchange narkive permalink

Das Senden eines Benutzernamens hat keinen Sinn. Auf der Serverseite speichern Sie Informationen darüber, welches Token zum Zurücksetzen des Kennworts mit welchem ​​Benutzer zusammenhängt. Wenn der Benutzer auf den Link klickt, wissen Sie genau, um welchen Benutzer es sich handelt. Sie erhalten den Benutzernamen basierend auf dem Token und zeigen ihn im Formular zum Zurücksetzen des Kennworts an.

John Wu
2020-06-23 12:00:32 UTC
view on stackexchange narkive permalink

Das Zurücksetzen eines Kennworts ist eine authentifizierte Operation und setzt voraus, dass sich der Benutzer auf sichere Weise identifiziert hat. Normalerweise erfolgt dies mit einem Benutzernamen und einem Passwort sowie einem zweiten Faktor. Der Benutzername und das Kennwort werden häufig gleichzeitig in derselben HTTP-Anforderung übermittelt. Dies ist keine Seltenheit und keine rote Fahne.

In einem Szenario mit vergessenem Kennwort ist die Notwendigkeit, den Benutzer zu authentifizieren, genau gleich. Dies bedeutet, dass sie ihren Benutzernamen sowie eine alternative Form von Anmeldeinformationen übermitteln (in Ihrem Fall verwenden Sie möglicherweise Herausforderungsfragen, die ich nicht kommentieren werde). Abgesehen davon ist es immer noch eine Authentifizierung, und es ist kein Problem, den Benutzernamen und die Anmeldeinformationen gleichzeitig zu übermitteln, genau wie bei der regulären Anmeldung.

Das Problem tritt auf, wenn Sie den Benutzernamen auf einem sammeln separate Seite. Dies ist häufig bei Workflows der Fall, die eine benutzerspezifische Herausforderung und Antwort beinhalten (z. B. Herausforderungsfragen, aber auch bei Out-of-Band-OTPs), da das System den Benutzernamen im Voraus kennen muss, damit es weiß, welche Fragen angezeigt werden sollen oder wohin Senden Sie das OTP. Die Versuchung besteht darin, den Benutzernamen auf einer separaten Seite zu sammeln und ihn dann als versteckte Formularvariable weiterzugeben. Dies unterliegt Manipulationen auf der Clientseite und stellt daher einen Vektor für einen IDOR -Angriff bereit.

Die Abschwächung besteht darin, das vergessene Kennwort "Sitzung" auf die gleiche Weise zu behandeln, wie Sie es verwalten eine gewöhnliche Anmeldesitzung; Verwalten Sie den Benutzernamen manipulationssicher, z. B. ein verschlüsseltes Cookie oder eine Sitzungsvariable. Versteckte Felder sind trivial zu manipulieren.

mti2935
2020-06-24 02:29:26 UTC
view on stackexchange narkive permalink

Ich habe ähnlich wie in ThoriumBRs hervorragender Antwort beschrieben, aber ohne eine temporäre Kennworttabelle zum Zurücksetzen verwendet, wie folgt:

  • Die Benutzer fragt nach einem Zurücksetzen des Kennworts.

  • Das System fragt nach der registrierten E-Mail.

  • Der Benutzer gibt E-Mail ein und nein Unabhängig davon, ob eine E-Mail vorhanden ist oder nicht, sagen Sie, dass Sie einen Reset-Link gesendet haben. Der Link wird durch Verschlüsseln des Benutzernamens und einer Ablaufzeit mit AES mit einem Schlüssel erstellt, der nur dem Server bekannt ist.

  • Wenn auf den Link zugegriffen wird, Der Link wird mit dem dem Server bekannten Schlüssel entschlüsselt, wobei der Benutzername und das Ablaufdatum angegeben werden. Wenn die Entschlüsselung erfolgreich ist, wird der Ablauf überprüft und wenn die Ablaufzeit nicht abgelaufen ist , wird ein Formular zum Zurücksetzen des Kennworts angezeigt. Der verschlüsselte Link wird in einem ausgeblendeten Feld im Formular ausgefüllt. Wenn das Formular gesendet wird, wird der Link erneut mit dem dem Server bekannten Schlüssel entschlüsselt, wobei der Benutzername und der Ablauf erstellt werden. Wenn die Entschlüsselung erfolgreich ist, wird der Ablauf erneut überprüft. Wenn die Ablaufzeit nicht abgelaufen ist, wird (und nur dann) das Kennwort für den Benutzer zurückgesetzt.

Benutzer erhält nur einen Link mit einem großen zufälligen Token.

Vilx-
2020-06-25 02:44:00 UTC
view on stackexchange narkive permalink

Ich habe bereits eine hoch bewertete Antwort auf genau diese Frage. Sie können darauf aufbauen, um andere Funktionen wie die Eingabe von E-Mails anstelle von Benutzernamen und Sicherheitsfragen einzuschließen.

  1. Der Benutzer gibt seinen Benutzernamen ein und klickt auf "Passwort vergessen". Ich empfehle auch die Option, die E-Mail-Adresse anstelle des Benutzernamens einzugeben, da Benutzernamen manchmal auch vergessen werden.
  2. Das System verfügt über eine Tabelle password_change_requests mit den Spalten ID , Time und UserID . Wenn der neue Benutzer die Taste drückt, wird ein Datensatz in der Tabelle erstellt. Die Spalte Zeit enthält die Zeit, zu der der Benutzer auf die Schaltfläche "Passwort vergessen" geklickt hat. Die ID ist eine Zeichenfolge. Eine lange zufällige Zeichenfolge wird erstellt (z. B. eine GUID) und dann wie ein Kennwort gehasht (was an und für sich ein separates Thema ist). Dieser Hash wird dann als 'ID' in der Tabelle verwendet.
  3. Das System sendet eine E-Mail an den Benutzer, die einen Link enthält. Der Link enthält auch die ursprüngliche ID-Zeichenfolge (vor dem Hashing). Der Link sieht ungefähr so ​​aus: http://www.mysite.com/forgotpassword.jsp?ID=01234567890ABCDEF . Die Seite forgetpassword.jsp sollte in der Lage sein, den ID-Parameter abzurufen. Entschuldigung, ich kenne Java nicht, daher kann ich nicht genauer sein.
  4. Wenn der Benutzer auf den Link in der E-Mail klickt, wird er auf Ihre Seite verschoben. Die Seite ruft die ID von der URL ab, hasht sie erneut und vergleicht sie mit der Tabelle. Wenn ein solcher Datensatz vorhanden ist und nicht älter als beispielsweise 24 Stunden ist, wird dem Benutzer die Aufforderung zur Eingabe eines neuen Kennworts angezeigt.
  5. Der Benutzer gibt ein neues ein Passwort, drückt OK und alle leben glücklich bis ans nächste Mal!
  6. ol>


Diese Fragen und Antworten wurden automatisch aus der englischen Sprache übersetzt.Der ursprüngliche Inhalt ist auf stackexchange verfügbar. Wir danken ihm für die cc by-sa 4.0-Lizenz, unter der er vertrieben wird.
Loading...