Frage:
Woraus sollte eine Bestätigungs-E-Mail bestehen?
HypeWolf
2018-11-05 05:39:08 UTC
view on stackexchange narkive permalink

Im Moment generiere ich eine in der Datenbank gespeicherte Zeichenfolge mit 25 Zeichen, die nur einmal verwendet werden kann und 30 Minuten nach der Benutzerregistrierung abläuft.

  http://example.com / security / activate / ZheGgUNUFAbui4QJ48Ubs9Epd  

Ich mache eine schnelle Datenbanksuche und die Logik lautet wie folgt:

Wenn das Konto nicht aktiviert ist UND wenn die E-Mail wurde nicht verifiziert UND der Validierungscode ist noch gültig. Aktivieren Sie das Konto, markieren Sie die E-Mail-Adresse als verifiziert und markieren Sie den Validierungscode als verwendet.

Alle 72 Stunden würde beispielsweise die Spülung abgelaufen und Dies dient dazu, dem Benutzer mitzuteilen, dass der angeklickte Aktivierungslink abgelaufen ist, z. B. wenn er am Tag danach auf seine E-Mail schaut und den Link ausprobiert.

Soll ich die Benutzer-UUID in die URL? Muss ich noch etwas hinzufügen?

Ich habe darüber nachgedacht, sicherzustellen, dass die IP-Adresse auf dem Registrierungsformular mit der IP-Adresse der Anfrage übereinstimmt, wenn der Aktivierungslink gedrückt wird, aber für mich lese ich hauptsächlich meine E-Mails weiter Mein Handy für solche Sachen, also wäre es ein Schmerz für UX.

Machen Sie sich nicht die Mühe, die IP-Adresse zu behalten / zu überprüfen.Es gibt so viele Gründe, warum sich IP-Adressen in kurzer Zeit ändern können - nur ein Wechsel von einem Café zu einem nebenan reicht aus.
Geben Sie zusätzlich zu den anderen Antworten immer eine Möglichkeit an, anzuzeigen, dass die Registrierung mit der angegebenen E-Mail-Adresse ein Fehler war / nicht existieren sollte.Bestätigungs-E-Mails, bei denen nur bestätigt werden kann, sind nicht sehr nützlich. * Aus persönlicher Erfahrung: Ich habe einen ziemlich gebräuchlichen Namen (in Ungarn) und erhalte ständig E-Mails mit der Bitte um Kontobestätigung für andere Personen, die fälschlicherweise meine Adresse anstelle ihrer angegeben haben. Die meisten von ihnen können nicht abgelehnt werden.Das Beste ist, wenn sie mich jede Woche "daran erinnern", mein Konto zu bestätigen, das ich nie erstellt habe. *
30 Minuten sind ein bisschen hart - ich würde es wahrscheinlich schaffen, in dieser Zeit von hier aus zu meiner E-Mail zu gelangen, aber es ist die gleiche Entfernung zurück zum Web, und ich bin mir ziemlich sicher, dass ich die Runde nicht legal verwalten konnteFahrt in weniger als 50 Minuten.
@MártonMolnár Es ist besser, den Benutzern beizubringen, dass der ordnungsgemäße Umgang mit dem Empfang einer unerwarteten Bestätigungs-E-Mail darin besteht, die E-Mail zu löschen (oder zu archivieren).Das Klicken auf Links in E-Mails, die Sie nicht erwartet haben, ist ein Risiko, das Sie nicht eingehen sollten.Das automatische erneute Senden der Bestätigungs-E-Mail ist eine schlechte Praxis, und ich würde diese als Spam kennzeichnen.
30 Minuten?Warum?Ich sehe nicht, wie Sie etwas erreichen.Ich erwarte * mindestens * 24 Stunden Zeit, um ein Konto zu aktivieren ...
Ich würde auch eine Funktion hinzufügen, bei der vor dem Hinzufügen der URL zur Website, wo sie in der Datenbank überprüft wird, sichergestellt wird, dass Sie nicht zweimal dieselbe Zeichenfolge verwenden
In der Tat sind 30 Minuten viel zu kurz.Ihre E-Mails werden möglicherweise in so kurzer Zeit nicht einmal an die Mailbox des Benutzers zugestellt.24 Stunden sind normal und bis dahin haben fast alle Leute die E-Mail erhalten.
Abgesehen davon ist dies für die Codegenerierung einer der Fälle, in denen es normalerweise einfacher ist, einfach eine zufällige UUID zu generieren und sie als erledigt zu bezeichnen.
Dies ist keine Sicherheitsüberlegung, aber stellen Sie sicher, dass es eine Möglichkeit gibt, die E-Mail erneut zu senden, wenn sie unterwegs verloren gegangen ist.Wenn Anmeldungen eher auf Benutzernamen als auf E-Mails basieren, lassen Sie die Benutzer sich anmelden und ihre E-Mails ändern, auch wenn das Konto noch nicht verifiziert ist - manchmal machen Sie einen Tippfehler :)
Sechs antworten:
Daisetsu
2018-11-05 05:48:25 UTC
view on stackexchange narkive permalink

Wie generieren Sie die 25-stellige Zeichenfolge, die Sie in die URL aufnehmen? Ist es völlig zufällig oder basiert es auf der aktuellen Zeit oder der E-Mail des Benutzers? Es sollte zufällig und nicht erraten sein.

Sie sollten sicherstellen, dass die Überprüfungsseite tatsächlich gerendert wird (nicht nur, dass eine GET-Anforderung aufgetreten ist). Browser wie Chrome (und Antivirenprogramme) laden häufig URLs, ohne dass der Benutzer explizit darauf klickt, um sie vorab abzurufen oder aus Sicherheitsgründen zu scannen.

Dies kann zu einem Szenario führen, in dem ein böswilliger Schauspieler (Eve) mithilfe der E-Mail-Adresse eines anderen (Alice) ein Konto erstellen möchte. Eve meldet sich an und Alice erhält eine E-Mail. Alice öffnet die E-Mail, weil sie neugierig auf ein Konto ist, das sie nicht angefordert hat. Ihr Browser (oder Antivirenprogramm) fordert die URL im Hintergrund an und aktiviert versehentlich das Konto.

Ich würde JavaScript auf der Seite verwenden, um die tatsächlich gerenderte Seite zu überprüfen, und außerdem einen Link in die E-Mail einfügen, über den Benutzer melden können, dass sie dieses Konto NICHT erstellt haben.

Super, vielen Dank für Ihren Einblick.Die Zeichenfolge wird zwar aus der crypto.randomBytes-Funktion von NodeJS generiert, und die Anwendung ruft bereits eine Javascript-Funktion auf, jedoch nicht aus dem von Ihnen angegebenen Grund.Dies ist eine gründliche Antwort, die Dinge hervorhebt, an die ich nicht gedacht habe.
Ich würde auch hinzufügen: Wenn Sie eine E-Mail-Änderungsfunktion haben, stellen Sie sicher, dass Sie alle vorhandenen Token löschen, wenn der Benutzer seine E-Mail-Adresse ändert.Dies verhindert, dass sich ein Benutzer mit einer gültigen E-Mail registriert, seine E-Mail in ein ungültiges Konto ändert und dann auf Ihren Registrierungslink klickt.
"Ich würde JavaScript auf der Seite verwenden, um die tatsächlich gerenderte Seite zu überprüfen". Es ist erwähnenswert, dass der JS * vom Benutzer blockiert * werden kann.Wenn ja, dann stempeln sie vielleicht auf den Link * denken *, der das Konto verifiziert hat, aber wenn sie versuchen, sich anzumelden, stellen sie beispielsweise nächste Woche fest, dass es gelöscht wurde.
@vlaz stimmt, aber Benutzer, die standardmäßig JavaScript blockieren, sind sich häufig bewusst, dass dies potenziell kritische Funktionen beeinträchtigt.Dies könnte gemindert werden, indem sichergestellt wird, dass die "Bestätigung", dass das Konto aktiviert ist, durch JavaScript sichtbar gemacht wird.Jeder Benutzer mit deaktiviertem JS würde eine Meldung sehen, die das Problem und die Lösung angibt.
Manchmal hat die Seite eine große Schaltfläche "Konto aktivieren".Dies macht deutlich, dass das Konto noch nicht aktiv ist, löst das JS-Off-Problem und ermöglicht es, gleichzeitig eine "Abbruchanforderung" daneben zu haben.
Behebt die Rückgabe einer Umleitung (302) an den realen Aktivierungscontroller das Problem des Antivirus-Prefetch?Ich meine ... folgen sie allen Weiterleitungen, bis sie auf einer Seite landen?
Können Sie erklären, warum die Vorteile von "* einem Link in der E-Mail, über den Benutzer melden können, dass sie dieses Konto NICHT erstellt haben *" die Vorteile der Schulung von Benutzern überwiegen, ** niemals ** auf Links in E-Mails zu klicken, die sie nicht waren?Erwarten Sie zu erhalten?
Wenn Sie garantieren möchten, dass die E-Mail-Adresse nicht versehentlich aktiviert wird, verwenden Sie eine POST-Anfrage.Es wird empfohlen, GET-Anforderungen niemals den Serverstatus ändern zu lassen.Siehe auch [The Spider of Doom] (https://thedailywtf.com/articles/The_Spider_of_Doom).
@usr-local-ΕΨΗΕΛΩΝ Wenn AV-Link-Scanner durch eine Umleitung gestoppt werden könnten, könnten Phishing- / Malware-Links leicht dieselbe Taktik anwenden.
Das klingt gut.Mein Fazit ist, dass Kontoaktivierungen nicht über HTTP GET erfolgen sollten.Eigentlich verstößt das jetzt, wo ich denke, gegen die HTTP-Verbsemantik
@usr-local-ΕΨΗΕΛΩΝ [Ich stimme zu, dass HTTP GET eine schlechte Wahl für Betriebsbefehle ist] (https://security.stackexchange.com/questions/135513/what-could-an-img-src-xss-do/135548#135548)
Kommentare sind nicht für eine ausführliche Diskussion gedacht.Diese Konversation wurde [in den Chat verschoben] (https://chat.stackexchange.com/rooms/85421/discussion-on-answer-by-daisetsu-what-should-a-verification-email-consist-of).
Maros D.
2018-11-05 14:06:46 UTC
view on stackexchange narkive permalink

Hinzufügen zur Antwort des Daisetsu (da ich noch keine Kommentare schreiben kann).

Es wäre nicht schlecht, ein Formular zu erstellen und den Benutzer zu bitten, ein Passwort zu erstellen. Auf diese Weise müsste der Benutzer ein neues Passwort eingeben und nach dem Absenden wird das Konto aktiviert. Es würde die Antiviren-Hintergrundprüfung lösen.

Die URL sollte so lang sein, wie es sich um eine zufällige Zeichenfolge handelt. Es besteht nur eine sehr geringe Wahrscheinlichkeit, dass Sie zwei Schlüssel mit demselben Inhalt gleichzeitig haben.

Das Überprüfen der IP-Adresse ist nicht gut, da einige ISPs möglicherweise IP-Adressen wechseln, sodass Sie jemanden blockieren, der sich registrieren möchte, dies aber nicht kann.

Ich habe diese Methode tatsächlich auf der neuesten Website verwendet, die ich entwickelt habe.Um dies hinzuzufügen, können Sie eine Datenbank mit allen von Ihnen generierten "zufälligen Zeichenfolgen" (auch bekannt als: Token) erstellen.Auf diese Weise können Sie sicherstellen, dass der Schlüssel nicht wiederverwendet wird.MySQL gibt den Fehler 1062 zurück, wenn Sie das Token als Primärschlüssel verwenden, wodurch es sehr einfach ist, zu überprüfen, ob der Schlüssel vorhanden ist.
@DavyM Vielen Dank.Zuerst habe ich versucht, einen Zusatz zu erstellen, bin aber darauf gekommen und habe eine hilfreiche Antwort erstellt.Sieht danach aus.
@IsmaelMiguel Ja.Sie können dies auch tun, wenn Sie sicher sein möchten, dass der Schlüssel in Zukunft nicht mehr verwendet wird.Sie können auch einen Zeitstempel hinzufügen, damit der Token nach einiger Zeit wieder verwendet werden kann (monatlich werden alte Token entfernt).
Das scheint zwar eine gute Idee zu sein, aber es gibt immer noch das Problem, dass jemand das Token hat und es wiederverwenden kann.Stellen Sie sich vor, ein Benutzer versucht, die E-Mail mit dem Token mithilfe des Betreffs zu finden.Der Benutzer merkt es sich aus einer anderen E-Mail.Und findet eine zufällige Passwort-Reset-E-Mail mit einem Token.Der Benutzer klickt darauf.Da Sie die Token gelöscht und neue neu erstellt haben, kann es * passieren *, wenn Sie Pech haben, dass dieser Token tatsächlich für eine andere Person bestimmt ist.Und sie ändern das Passwort für diese andere Person.Jetzt haben sie Zugriff mit einem anderen Konto.
@IsmaelMiguel Sie haben recht.Daran habe ich nicht gedacht.
Future Security
2018-11-06 02:07:46 UTC
view on stackexchange narkive permalink

Ihre E-Mail sollte einen Aktivierungscode und keinen Link enthalten. Sie sollten keinen Link für die Kontoverwaltung in einer E-Mail senden. Wenn Sie (die legitime Partei) E-Mail-Links (insbesondere mit langen Zeichenfolgen) an Benutzer senden, ist es etwas schwieriger, legitime E-Mails von Phishing-Versuchen zu unterscheiden.

Der Aktivierungscode sollte aus bestehen Zeichen, die leicht kopiert und eingefügt werden können (keine Leerzeichen, '+', '-' usw.) und die auch leicht manuell eingegeben werden können. Buchstaben und Zahlen funktionieren. Die Sicherheit des Aktivierungscodes hängt davon ab, dass er nicht vorhersehbar ist. Sie leiten den Wert mithilfe des sicheren Zufallszahlengenerators des Systems ab, genau wie Sie es mit Sitzungs-IDs für Cookies tun sollten.

Aktivierungscodes sollten in einer Datenbanktabelle gespeichert werden, jede Zeile mit einer Profil-ID, die Aktivierung Code * sup> und die Ablaufzeit. Sie möchten die Profil-ID oder die Ablaufzeit nicht in ein Cookie, eine URL oder den Aktivierungscode einfügen. ** sup> Ein böswilliger Benutzer könnte die ID manipulieren, um ein anderes Konto zu übernehmen. Sie müssen diese Dinge serverseitig überprüfen, da Ihre Sicherheitsrichtlinie Client-Daten nicht blind vertrauen kann.

Der Aktivierungscode sollte über eine POST-Anforderung gesendet werden. Leiten Sie Benutzer automatisch zur Kontoaktivierungs-URL um (die nur https://example.com/security/activate sein kann), wenn Sie mit dem Rest der Registrierung fertig sind. Erleichtern Sie den erneuten Zugriff auf die Kontoaktivierungsseite, falls diese versehentlich geschlossen wird.

Sie möchten nicht, dass eine GET-Anforderung eine Aktion ausführt. Ein Link wird möglicherweise ohne Benutzerinteraktion besucht (aufgrund von Browser-Prefetching oder E-Mail-Sicherheitsdiensten). Darüber hinaus können durch das Einfügen von Geheimnissen in eine URL vertrauliche Daten verloren gehen. (Über Empfehlungsheader oder Browser-Addons.)

Machen Sie sich keine Sorgen um die IP, sie kann sich dennoch ändern. (Gleiches gilt für User Agent.)

Ich weiß nicht, ob eine Stornierungsfunktion wünschenswert ist. Ich verwende die Links zum Abbestellen nicht einmal in unerwünschten E-Mails, da hiermit möglicherweise festgestellt werden kann, ob mit einer E-Mail-Adresse ein Mensch verknüpft ist oder nicht. Wenn der Aktivierungscode lang genug ist, um roher Gewalt zu widerstehen, oder wenn Sie die Anzahl der Aktivierungscodeversuche begrenzen, sehe ich keinen Schaden darin, den Aktivierungscode irgendwann ablaufen zu lassen.

Andererseits Es könnte hilfreich sein, die Anzahl unerwünschter E-Mails zur Kontoaktivierung zu reduzieren. Sie können die Anzahl der E-Mails, die Sie an eine Adresse senden, begrenzen, um höflich zu sein. Sagen Sie maximal 3 pro Tag und maximal 5 pro Monat. (Ich weiß nicht, ob das zu hoch oder zu niedrig ist.) Als Nichtbenutzer würde ich E-Mails von Ihrer Website einfach automatisch löschen oder automatisch als gelesen markieren.

Es gibt viele Variablen, die für unerwünschte Aktivierungs-E-Mails berücksichtigt werden müssen. Höchstwahrscheinlich hat dies mehr mit der Benutzererfahrung als mit der Sicherheit zu tun. Sie können sogar die Funktion "Aktivierung abbrechen und niemals E-Mails an diese Adresse senden, da ich mich nie registrieren werde" bereitstellen. Dies hat jedoch offensichtliche Probleme. (Sie müssen auch noch die E-Mail-Adresse der Person überprüfen.)

* Es tut nicht weh, den Aktivierungscode zu hashen. Wie bei Kennwörtern ist auch das Hashing nicht kritisch, da jeder Code einmalig verwendet wird, keine privaten Informationen enthält, vom Server zufällig generiert wird und abläuft. Sub>

** Sie könnten Manipulationen mit einem kryptografischen MAC tatsächlich verhindern, aber ich würde den meisten Entwicklern dringend davon abraten, dies zu versuchen. Kryptographie ist schwer zu finden. Sub>

Wow <3 Danke!Würden Sie einen CD-Key-ähnlichen Token verwenden?`2ZRIF-07SWU-ZQVA7-SVSIN-OCFDC` Diese Art von Code, der in der Mitte der E-Mail groß ist, würde es einfach machen, den Zweck mit dem Aktivierungslink unten zu verstehen.Diese Zeichenfolge könnte mit crypto.randomBytes () generiert werden, aber mein Anliegen ist das kurze Alphabet, aber dann wieder die Zeichenfolge, wenn 25 Zeichen so lang sind, dass es eine Weile dauern sollte, bis eine Brute-Force erkannt wird.Irgendein großartiger Artikel über kryptografischen MAC?: D.
@HypeWolf 36 ist nicht so kurz;36 ^ 25 ist groß genug für mich.
@wizzwizz4 Richtig.Vielleicht bin ich nur paranoid.
@HypeWolf Paranoia und gute Sicherheit sind nicht unbedingt miteinander verbunden.Sie verwenden eine GET-Anforderung, um eine Aktion auszulösen (wenn Sie stattdessen zu einer Seite mit einer Schaltfläche weitergeleitet werden sollen, die eine POST-Anforderung zum Auslösen der Aktion sendet).
Sie sagen: "Aktivierungscodes sollten in einer Datenbanktabelle gespeichert werden".Könnte es sinnvoll sein, noch einen Schritt weiter zu gehen und es zu hashen?Da es sich um eine zufällige Zeichenfolge handelt, können Sie sich für ein festes Salz entscheiden (andernfalls müssen Sie es von der Client-Seite beziehen).
Ich bin mit dieser Antwort nicht einverstanden.Wir sprechen hier von einem einmaligen Code.All die verschiedenen Bedrohungen durch Sniffing, Lesen von Proxy-Protokolldateien usw. sind dagegen nutzlos.Für einen MitM-Angriff macht es keinen Unterschied.Ich sehe keinen Sicherheitsgewinn, wenn ich den Prozess komplizierter mache und ein einfaches GET nicht zulasse.
@Tom Andere Antworten und Kommentare haben darauf hingewiesen, dass ein GET möglicherweise versehentlich ausgelöst wird, z.von einem Sicherheitsscanner.Ich stimme auch zu, dass wir Benutzer im Allgemeinen davon abhalten sollten, auf Links in E-Mails zu klicken, obwohl dies wahrscheinlich ein verlorener Kampf ist, bis Paypal ihre echten Ankündigungen weniger wie Phishing-Versuche aussehen lässt.
@Thierry Auf jeden Fall.Oder vielleicht H (Festes Salz, E-Mail-Adresse, Aktivierungscode).Es ist jedoch wahrscheinlich ein geringes Risiko, das Hashing des Codes zu überspringen.(Ich glaube, weil es einmalig verwendet wird, keine privaten Informationen enthält, vom Server generiert wird und abläuft.) Passwörter sollten natürlich * definitiv * gehasht werden.
@HypeWolf Die Alphabetgröße ist nicht wichtig.Nur die Anzahl der möglichen Codes.Wenn Sie Ihrem Profil / Bestätigungscode einen Zähler hinzufügen und ihn nach zu vielen falschen Antworten ungültig machen, können Sie einen viel, viel kürzeren Code verwenden.Ich würde sogar Vokale fallen lassen, um zu vermeiden, dass echte Wörter zufällig geschrieben werden.Behandle O und 0 als identisch, I, L und 1 ebenfalls.Leerzeichen / Trennzeichen entfernen.usw. Die Anzahl der möglichen unterschiedlichen Codes ist der einzige Faktor, der die Sicherheit beeinflusst.Alle anderen Entscheidungen sind Fragen zur Benutzererfahrung.
@Tom Sie korrigieren, keines dieser Dinge macht einen Unterschied.Das Einfügen des Codes in einen GET-Parameter im Vergleich zum Einfügen in einen POST-Parameter ist jedoch wichtig.Ein GET kann falsch positiv sein, wenn Sie nicht nach demselben Sitzungscookie suchen.Möglicherweise registriert sich jedoch jemand auf seinem Laptop, liest jedoch E-Mails auf seinem Telefon.Oder das Cookie kann gelöscht werden, wenn der Browser nach der Registrierung, aber vor der Überprüfung geschlossen wird.Außerdem besteht der einzige Sicherheitsunterschied darin, ob Sie Benutzer für Phishing vorbereiten oder nicht.(Wir sprechen nicht über Systeme zum Zurücksetzen von Passwörtern. Das ist ganz anders.)
@IMSoP mag es sein, aber was auch immer ausgelöst wird, wird schlampig gemacht.Es sollte HEAD oder OPTIONS verwenden, je nachdem, was überprüft werden soll.Es gibt Dinge zu beachten und die Hauptsache ist, dass GET idempotent sein sollte, aber in diesem Anwendungsfall nicht.
@HypeWolf Ich würde einen solchen Sicherheitscode mit Bindestrichen nicht verwenden, da beim Versuch, darauf zu doppelklicken, nur ein Teil und nicht die ganze Zahl ausgewählt wird.
@CharlieHarding In der Tat, guter Fang!
Empfehlen Sie Bestätigungscodes (anstelle von Bestätigungslinks) auch für die wichtigsten E-Mails zur Kontoverwaltung wie E-Mail-Bestätigung, Zurücksetzen des Passworts, E-Mail-Änderung usw.?
@lonix Ja.Für beide Methoden generieren Sie ein zufälliges Token.Ein Bestätigungslink fügt dieses Token in die URL ein.Ein Bestätigungscode ist ein Token, das der Benutzer in ein HTML-Formular eingibt.Das einzige Risiko, das für Bestätigungscodes spezifisch ist, das ich mir vorstellen kann, besteht darin, das Token aus Gründen der Benutzerfreundlichkeit zu verkürzen.Wenn Sie dieselbe Bestätigungscodelänge verwenden, die Sie für URL-Token verwendet hätten, ist die Bestätigungscodemethode mindestens genauso sicher.
@FutureSecurity Stimmt, aber in Wirklichkeit ist der Code ein sehr kurzes Token (sagen wir 6-9 Ziffern oder so), während das Token des Links eine monströse Hex-Zeichenfolge ist.Unter diesen Umständen wären Sie sicherlich gegen Codes (und für Links)?
@lonix Es muss nicht so kurz sein, um verwendbar zu sein.Und der Code muss nicht zu lang sein, um sicher zu sein.Kurze Schlüssel und kurze Passwörter sind schlecht, aber das Bestätigungstoken ist keines davon.Ein kurzes Passwort kann durch einen langsamen Online-Angriff brutal erzwungen werden.Im Gegensatz zu Passwörtern können Token jedoch ungültig werden, wenn ein Client zu oft den falschen Code eingibt.Im Gegensatz zu Schlüsseln kann ein Hacker nur feststellen, ob er den richtigen Code erhalten hat, indem er ihn an den Server sendet.
@lonix Sie könnten Base-32 eine zufällige 60-Bit-Zahl codieren, die Ihnen 12 Zeichen gibt.Sie können dieses Token auf 10 falsche Antworten beschränken.Sie müssten Millionen von Vermutungen pro Sekunde einreichen, wenn Sie das Passwort eines anderen innerhalb von tausend Jahren zurücksetzen möchten.Das ist ohne Ratenbegrenzung oder Überwachung.Je nachdem, wie wertvoll das, was Sie schützen möchten, ist, können Sie zu Ihrer Zufriedenheit Zeichen hinzufügen oder entfernen.
@lonix Technisch gesehen ist es möglich, ein Hash-Token offline zu knacken, wenn jemand Lesezugriff auf eine Datenbank erhält, während der Authentifizierungsserver aktiv ist.(Es tut nicht weh, die Token zu hashen, auch wenn sie kurz sind.) Um dieses Problem teilweise zu mindern, sollte der Token nach einiger Zeit ablaufen.Fehlende Hacks, Lecks und Insider-Angriffe gibt es kein Offline-Cracken, das ein Hacker nutzen könnte, es sei denn, der Server unternimmt etwas Seltsames wie das Senden des Hash des Tokens an Clients.
@FutureSecurity Vielen Dank für Ihre Erkenntnisse!Sie haben mich überzeugt, Codes anstelle von Links zu verwenden.Ich gebe dem Benutzer 3 Chancen, den Code innerhalb von 10 Minuten richtig zu machen, und mache ihn dann ungültig.
user135823
2018-11-06 14:15:12 UTC
view on stackexchange narkive permalink

Wie bei allem, wo Sie Sicherheitspraktiken anwenden, müssen Sie die Gefährdungs- und Bedrohungsbewertung für Ihre einzigartige Umgebung und Ihren Anwendungsfall bewerten. Die vorhandenen Antworten bieten zahlreiche Berührungspunkte für diese Auswertung sowie Hinweise für Dinge, die vermieden werden sollten, z. B. durch GET ausgelöste Aktionen. Stattdessen werde ich mich mehr auf den "Benutzer" -Teil der UX konzentrieren. Ich werde auch auf viele der auf der Seite verstreuten Kommentare eingehen.

Genau das, was Sie mit der durch E-Mail ausgelösten Aktion "überprüfen", ist ebenfalls ein zu berücksichtigender Faktor. Wenn Sie lediglich bestätigen, dass es sich um eine gültige E-Mail-Adresse handelt, ist fast jede Aktion ausreichend. Das Überprüfen der E-Mail, der Absicht, ein Konto zu erstellen, und der Tatsache, dass der Benutzer, der die E-Mail erhält, der Benutzer ist, der die Kontoerstellung initiiert hat, erfordert etwas mehr Aufwand.

Eine "Anstrengung" sollten Sie nicht muss jedoch das Versenden von Erinnerungs-E-Mails übernehmen. Angenommen, der Benutzer hat das Konto absichtlich erstellt, eine gültige E-Mail-Adresse verwendet und möchte das Konto für jeden Zweck verwenden, den Sie Konten anbieten. Er sucht nach der E-Mail und führt den Aktivierungsprozess durch, sobald er dazu in der Lage ist. Der Link, der Code oder was auch immer läuft möglicherweise ab, bevor sie ihn verwenden, wenn sie während des Wartens auf die E-Mail von anderen Angelegenheiten abgelenkt werden. In solchen Fällen ist es in Ordnung, ihnen zu erlauben, die Bestätigungs-E-Mail erneut zu senden. Eine Erinnerungs-E-Mail ist jedoch viel eher ein Spam-Auslöser als ein Vorteil für den Benutzer.

Als Benutzer schätze ich es, Optionen zur Aktivierung / Überprüfung meines Kontos zur Verfügung zu haben. Der häufigste Optionssatz, auf den ich gestoßen bin, besteht darin, dass die E-Mail einen Link enthält, auf den ich entweder klicken oder & einfügen kann, und einen Bestätigungscode, den ich in ein Formularfeld auf einer Seite in meinem eingeben kann Bereich für Kontoeinstellungen auf der Website. Der Bestätigungscode ist selten etwas anderes als eine Ganzzahl mit einer Länge von 5 bis 9 Stellen.

Die Bestätigungs-E-Mails, die mir als Benutzer das größte Vertrauen geben, sind diejenigen, die einen krypto aussehenden Hash in der URL haben ( / verify? l = lgGS2SBjMTU4NjkwNjYxMjI5MDBhZDk2YjEyMzMzYjNhZmQxOb ) Seite einzigartig für mich, wo ich dann das Passwort eingeben muss, mit dem ich das Konto erstellt habe. Die Verwendung des Hashs bestätigt, dass der Link in einer E-Mail empfangen wurde, die nicht erraten oder brutal erzwungen wurde, und überprüft somit, ob die E-Mail gültig ist. Durch das Bereitstellen dieser eindeutigen Seite vor allen anderen Aktionen kann der Server die E-Mail, an die er gesendet wurde, als "gültig" markieren, ohne die Kontoerstellung zu bestätigen. Die Eingabe des Kennworts bestätigt, dass sich am anderen Ende ein Akteur befindet, im Gegensatz zu Antiviren-, Malware-Erkennungs- oder Pre-Fetch-Vorgängen. Die Gültigkeit des Passworts bestätigt mit hinreichender Sicherheit, dass der Empfänger der E-Mail und der Ersteller des Kontos dieselbe Person sind.

Die vorgeschlagene Frist von 30 Minuten scheint ein wenig zu sein schwerwiegend, während ein Zeitraum von 24 Stunden möglicherweise zu lang ist, wenn Ihre Bedrohungsanalyse darauf hinweist, dass Ihre Exposition innerhalb von 24 Stunden nicht akzeptabel ist. Ich glaube, dass 2 Stunden für fast jede Benutzerumgebung ausreichen sollten. Insbesondere dann, wenn die Möglichkeit zum erneuten Senden der Überprüfung verfügbar ist. Selbst wenn Sie ein mobiles Gerät mit einer 14-kb / s-Verbindung zu einem Remote-POP-Konto verwenden, sollte der Austausch innerhalb von 120 Minuten abgeschlossen sein.

Die Verwendung von JS zur Überprüfung menschlicher Handlungen kann problematisch sein. JS kann deaktiviert werden und ist viel häufiger als viele Webentwickler gerne wissen würden. Zweitens können Werbeblocker JS pro Site oder pro Quelle blockieren, selbst wenn JS im Browser aktiviert ist. Ich blockiere viele JS-Quellen, einschließlich der Analyseskripte von Google, auf globaler Basis und liste einige für Websites wie Stack Exchange auf, wo ich bereit bin, sie bei der Verwendung meiner Daten zu unterstützen.

Das Einfügen eines Links in die E-Mail oder auf die Bestätigungsseite zum "Kündigen" des Kontos ist eine Verschwendung. In der E-Mail ist dies tatsächlich kontraproduktiv, da dies darauf hindeutet, dass das Klicken auf einen Link zu einem Konto, das Sie nicht möchten, eine gute Idee ist. Stattdessen sollte die E-Mail die Angabe enthalten, dass das Konto nicht bestätigt und möglicherweise gelöscht wird, wenn Sie nichts tun. Ein Link zum Abbrechen auf der Bestätigungsseite ist noch schlimmer, da er schlechtes Verhalten belohnt. Ich erhalte häufig E-Mails als Teil eines alten Google-Snafu, die an ein anderes Google Mail-Konto weitergeleitet werden, und ich gehe davon aus, dass das Gegenteil auch für das andere Konto gilt. [Früher hat Google keine gepunkteten und nicht gepunkteten Benutzernamen zusammengeführt, daher sind mein gepunkteter Benutzername und die nicht gepunktete Version eines anderen Benutzers unterschiedliche Konten. Google wird jedoch gelegentlich ausrutschen und ich erhalte trotzdem eine E-Mail :(]

Wie eng Sie die "verifizierte" E-Mail-Adresse mit dem Aktivierungslink koppeln, hängt von Ihrem Anwendungsfall und Ihrer Bedrohungsanalyse ab. Ich bin leicht verärgert, wenn ich mein Konto nach dem Ändern der zugehörigen E-Mail-Adresse erneut validieren muss. Die Akzeptanz des Prozesses ist proportional zu meinem "Wert" des Kontos. Für mein Bankkonto, PayPal usw. akzeptiere ich zu 100%. Bei PcPartsPicker würde ich dies jedoch zu etwa 15% akzeptieren ein Prozess.

Ignorieren Sie die IP-Adresse und / oder den Benutzeragenten. In diesem Fall werde ich häufig Websites anzeigen und mithilfe meines Mobilgeräts ein Konto erstellen. Ich werde nicht , jedoch offene E-Mails darauf. Wenn ich ein Konto erstelle und erfahre, dass ich es irgendwie überprüfen oder bestätigen muss und E-Mail die angebotene Methode ist, werde ich Warten Sie, bis ich nach Hause komme, um die E-Mail auf meinem Desktop zu öffnen, wo ich sie überprüfen kann. Die IP und der Benutzeragent sind daher sehr unterschiedlich. Mein Passwort bleibt jedoch das gleiche, und das sollte ausreichen, um mich als ursprünglichen Kontoersteller zu verifizieren.

Denken Sie daran, dass E-Mails ungefähr so ​​sicher sind wie das Jumbo-tron auf dem Times Square Gehen Sie entsprechend vor.

"Selten ist der Bestätigungscode etwas anderes als eine ganze Zahl, 5 bis 9 Stellen lang."dies ist hervorzuheben. Mit einem einmaligen Code, der in 30 Minuten abläuft, sind 25 Zeichen völlig übertrieben.Selbst 6 alphanumerische Zeichen erfordern 600.000 POSTs / Sek., Um 50% in 30 Minuten abzudecken.Drosseln Sie den Überprüfungsdienst, um eine Hundertstelsekunde zu verzögern, und ein Gegner kann höchstens 0,008% des Schlüsselbereichs scannen. Er hat eine Chance von 1 zu 12.000, vorausgesetzt, er verbraucht Ihren gesamten Überprüfungsdienst 30 Minuten lang ...
@TemporalWolf haben Sie die Tatsache berücksichtigt, dass der Gegner parallel scannen kann?
@PaŭloEbermann Wenn Sie Ihren Überprüfungsdienst drosseln, ist die Anzahl der Schlüssel, die gescannt werden können, begrenzt.Es geht darum, das Risiko auszugleichen.Für eine Bank?Wahrscheinlich nicht.Für ein kleines Unternehmen?Wahrscheinlich.Ich würde anfangen zu überlegen, ob die Anzahl der neuen Konten in einem Schiebefenster etwa 100 überschreitet.Dies bietet immer noch eine Wahrscheinlichkeit von <1%, dass jemand den Code eines anderen errät, und eine Wahrscheinlichkeit von 100%, dass der Versuch erkannt wird (unter der Annahme einer gewissen Überwachung).6 Zeichen sind ~ 32 Bit Entropie.10 ist ~ 52.25 ist ~ 130.Sie steuern die Brute-Force-Geschwindigkeit über Ihren Verifizierungsdienst.
Damon
2018-11-07 16:40:34 UTC
view on stackexchange narkive permalink

Eine Bestätigungs-E-Mail benötigt nur wenige Dinge, um einigermaßen sicher und benutzerfreundlich zu sein:

  1. Dem Benutzer muss klar sein, was los ist. Wenn erklärt wird, warum diese E-Mail empfangen wird (z. B. "... jemand hat das Konto BLAH auf unserer Website registriert, um dies zu bestätigen ..." ), werden die meisten dummen Fehler ausgeschlossen und das Fischen von E-Mails ziemlich gut vereitelt . Sie wissen hoffentlich, ob Sie gerade ein Konto bei einem Dienst registriert haben oder nicht (es sei denn, Sie sind vollständig dement). Es ist also keine Überraschung, eine E-Mail zu erhalten, die dies erklärt. Auf der anderen Seite sollte eine solche E-Mail, die weiß, dass Sie sich nirgendwo registriert haben, (hoffentlich) verdächtig genug sein. Wenn dies nicht der Fall ist und der Benutzer auf einen zufälligen Link klickt, der per E-Mail gesendet wird, können Sie sowieso nichts tun, ohne zu wissen, welche E-Mails Personen, die Sie nicht kennen, möglicherweise empfangen oder nicht erhalten.
  2. Ein zufälliges (nicht sequentielles!) Token, das relativ lang ist (lang genug, um sicherzustellen, dass es nicht erraten werden kann und nicht kollidiert), wird an den Server zurückgegeben. Dieses Token wird zum Vergleich auch in der Datenbank gespeichert. Es spielt keine Rolle, wie lange es genau ist und welches Format es hat. Es muss nicht lesbar sein. Alles über 20 Zeichen (unter der Annahme einer Base64-Codierung) sollte funktionieren, aber ich würde 40 Zeichen verwenden, um sicherzugehen, da es Sie nicht wirklich etwas kostet. Eine 240-Bit-Pseudozufallszeichenfolge ist garantiert eindeutig und nicht erratbar. Der Einfachheit halber würde ich es tatsächlich zu einem Link machen, und der Link kann tatsächlich eine GET -Anforderung sein. Ja, Benutzer sollten nicht auf Links klicken, aber sie werden es trotzdem tun (Sie werden sie nicht unterrichten!). Auf der anderen Seite ist die Benutzererfahrung viel besser als das Kopieren und Einfügen einer dunklen Zeichenfolge.
  3. Ein HTML-Formular mit einer Schaltfläche "Klicken zur Bestätigung", die die Daten erneut POST enthält. Dies garantiert, dass das spekulative Laden von URLs keine (unbeabsichtigten oder sogar böswilligen) Ereignisse zulässt. dass der Benutzer, dem die E-Mail-Adresse gehört, nichts davon weiß. Das Formular sollte eine angemessene Menge an Informationen enthalten, damit der Benutzer weiß, was los ist, und als letzte Chance, "WTF?" Falls der Benutzer dieses Konto nicht registriert hat.
    Wenn Sie sich Sorgen um Roboter machen, kann das Formular auf Wunsch ein "Ich bin kein Roboter" enthalten (ich persönlich Halten Sie dies für überflüssig, aber Ihr Kilometerstand kann variieren.
  4. Ein angemessenes Ablaufdatum (oder eine angemessene Ablaufzeit). Was ist vernünftig? Niemand kann eine endgültige Antwort geben, die für alle gut ist. Ich würde sagen, dass alles von 4 Stunden bis zwei Tagen wahrscheinlich gut ist. Wenn Sie sich für etwas registrieren, erhalten Sie normalerweise Ihre Bestätigungsmail innerhalb von 5-10 Sekunden und sitzen vor dem Computer und warten darauf. Könnte länger sein, wenn Sie typische Unternehmens-E-Mails im Paranoia-Modus verwenden, die Minuten für das Scannen jeder externen E-Mail benötigen. Möglicherweise erhalten Sie einen Anruf oder müssen irgendwo in die Mitte gehen. Daher ist es kein Fehler, den Token für ein paar Stunden oder einen Tag gültig zu haben. Außerdem kann E-Mail verzögert werden (selten, aber es kommt vor).
    Andererseits macht es keinen Sinn, Speicherplatz zu verschwenden, indem Bestätigungs-Token (und das Blockieren von Kontonamen!) Wochenlang aufbewahrt werden , Monate oder Jahre. Dies verbraucht nicht nur vergeblich Ressourcen, sondern jemand, der dies nicht innerhalb von ein oder zwei Tagen bestätigt, wird es wahrscheinlich sowieso nie tun. Oder sie könnten sich einfach ein anderes Mal neu registrieren. Was wirklich nichts kostet.
  5. ol>
Tom
2018-11-06 20:27:57 UTC
view on stackexchange narkive permalink

Aus Ihrer Frage gehe ich von den folgenden Annahmen aus, und wenn eine davon ungültig ist, gilt dies auch für meine Antwort:

  1. Der Benutzer registriert sich auf Ihrer Webseite und legt währenddessen den Benutzernamen / die E-Mail-Adresse und das Kennwort fest Registrierung
  2. Die E-Mail-Überprüfung hat den Zweck sicherzustellen, dass sich der Benutzer mit einer richtigen E-Mail-Adresse registriert hat.
  3. Die Aktivierung des Kontos ist das einzige, was die E-Mail-Bestätigung Mail-Link tut. Ein Zurücksetzen des Passworts oder andere solche Funktionen sind nicht zulässig. Grundsätzlich wird "UPDATE user SET enabled = true WHERE token =% 1" ausgeführt.
  4. ol>

    In diesem Fall ist Ihr Ansatz aus Sicherheitsgründen absolut in Ordnung. 25 Zeichen geben Ihnen genügend Sicherheit gegen zufällige Kollisionen und Brute-Force-Versuche, die einmalige Verwendung schützt vor Schnüffeln und ähnlichen Angriffen und das Einzige, was jemand erreichen kann, ist die Aktivierung eines Kontos.

    Vielleicht möchten Sie Um die Benutzer-ID einzuschließen, wenn Sie aus Leistungsgründen viele Benutzer haben (UPDATE: nicht wirklich, siehe Kommentare unten) Wenn Sie den Benutzer anhand eines Zeichenfolgentokens finden, wird ein Tabellenscan durchgeführt, während Sie ihn anhand von finden ID und dann nur das Abrufen und Vergleichen der Zeichenfolge ist eine Indexsuche. Dadurch wird jedoch die Benutzer-ID angezeigt, die Sie möglicherweise ausführen möchten oder nicht.

"Das Finden des Benutzers anhand eines Zeichenfolgentokens führt zu einem Tabellenscan" - nicht, wenn Sie einen Index für die Tokenspalte erstellen.Ein Textindex ist möglicherweise geringfügig langsamer als ein numerischer Index, es gibt jedoch überhaupt keinen Grund, einen Tabellenscan durchzuführen.
Indizes sind nicht kostenlos.Würden Sie einen Index für die Tabelle erstellen, der ** einmal ** in der Lebensdauer jeder Zeile verwendet wird?(Außerdem ist es für die meisten Zeilen null. Hm, es könnte deshalb tatsächlich eine gute Leistung haben.)
Sie können einfach eine separate Tabelle (mit Index) für die Aktivierungstoken haben, anstatt diese in die Benutzertabelle einzufügen.
Verwenden Sie eine separate Tabelle für Aktivierungstoken: "Token", "UID", "Ablauf".Führen Sie bei einer HTTP-Anforderung mit einem Token `DELETE FROM TokenTable WHERE expiry
Einverstanden, @GypsySpellweaver, das wäre eine gute Lösung.


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...