The Copenhagen Book: Leitfaden zur Implementierung von Authentifizierung in Webanwendungen
(thecopenhagenbook.com)- Ein grundlegender Leitfaden, der bei der Konzeption der Implementierung von Authentifizierung in Webanwendungen als Referenz dienen kann und darauf abzielt, Lücken in online verfügbaren Authentifizierungsressourcen zu schließen
- Eine kostenlose Open-Source-Ressource, die von der Community gepflegt wird
- Einige Inhalte können meinungsbehaftet oder unvollständig sein; daher ist es sinnvoll, sie eher als ergänzendes Material statt als alleinige Grundlage zu verwenden
- Es wird empfohlen, sie zusammen mit der OWASP Cheat Sheet Series als Referenz für Authentifizierungssicherheit zu nutzen
- Vorschläge oder Bedenken können durch das Erstellen eines neuen Issues eingebracht werden, sodass man zur Verbesserung der Dokumentation beitragen kann
Zweck und Charakter des Dokuments
- The Copenhagen Book bietet allgemeine Leitlinien, die bei der Implementierung von Authentifizierung (auth) in Webanwendungen als Referenz dienen können
- Die Arbeitsweise ist wie folgt
- Kostenlos verfügbar
- Open Source
- Von der Community gepflegt
- Die Inhalte können mitunter meinungsbehaftet oder nicht vollständig sein
Weitere Referenzen und Beteiligungsmöglichkeiten
- Bei der Implementierung von Authentifizierung wird empfohlen, zusätzlich die OWASP Cheat Sheet Series zu konsultieren
- Bei Vorschlägen oder Bedenken kann ein neues Issue erstellt werden
1 Kommentare
Hacker-News-Kommentare
Wenn ich mich nicht irre, stammt dieser Text wohl vom Autor von Lucia, einer beliebten Authentifizierungsbibliothek für TypeScript.
Kürzlich wurde angekündigt, dass die Lucia-Bibliothek nicht mehr als ergonomischer Weg zur Implementierung von Authentifizierung angesehen wird; die Bibliothek soll eingestellt und durch eine Reihe schriftlicher Guides ersetzt werden.
Die ersten Vorschauen der Guides waren gut zu lesen und passten auch gut zu The Copenhagen Book.
https://github.com/lucia-auth/lucia
https://github.com/lucia-auth/lucia/discussions/1707
https://lucia-next.pages.dev/
Selten ist, dass jemand die Anzeichen einer explodierenden Komplexität gesehen, anerkannt hat, dass die Bibliothek selbst für ihn nicht mehr nützlich ist, und dann dem üblichen Pfad der Bibliotheks-Aufblähung demütig ausgewichen ist.
Tatsächlich brauchen 99 % der Leute nur Login/Logout, und das ist enorm nützlich, wenn es als Bibliothek bereitgestellt wird.
Wenn man Web-8.0-Passkeys über WASM-Elliptic-Curve-Sockets anbieten muss, kann man es selbst bauen oder Auth0 verwenden; aber jemandem, der eine CRUD-Koch-App baut, die OAuth-Spezifikation samt Fallstrickliste hinzulegen und zu sagen, er solle Authentifizierung selbst bauen, ist seltsam.
Diese Person sollte sich auf die eigentliche Idee konzentrieren, statt die Sanitärtechnik neu zu erfinden, und viele werden es am Ende falsch implementieren, sodass sie faktisch gar keine Authentifizierung haben.
Dieser Teil ist falsch: „E-Mail-Adressen unterscheiden nicht zwischen Groß- und Kleinschreibung.“
https://thecopenhagenbook.com/email-verification
Nach dem E-Mail-Standard unterscheiden E-Mail-Adressen zwischen Groß- und Kleinschreibung.
Wenn man eine E-Mail beim Versand in Kleinbuchstaben umwandelt, kann sie an die falsche Person gehen, und bei Authentifizierung ist das gefährlich.
Viele bekannte E-Mail-Anbieter entscheiden sich dafür, Groß-/Kleinschreibung nicht zu unterscheiden, aber eine Website, die allgemeine Authentifizierung behandelt, sollte den allgemeinen Fall empfehlen.
https://stackoverflow.com/questions/9807909/are-email-addres...
Außerdem ist nicht immer eindeutig, was die entgegengesetzte Groß-/Kleinschreibung eines Zeichens ist, und das kann sich im Lauf der Zeit ändern. Zum Beispiel wurde das deutsche Großbuchstaben-ẞ erst 2008 zu Unicode hinzugefügt; in der allgemeinen Programmierung ist es daher besser, Groß-/Kleinschreibung nach Möglichkeit zu vermeiden.
Der Standard sagt das eine, Implementierungen verhalten sich anders, und wenn man sich in diesem Fall nur an den Standardtext hält, bekommt man in der realen Welt Probleme.
So werden E-Mails an die Adresse mit der ursprünglich eingegebenen Schreibweise gesendet, und der Login funktioniert unabhängig von Groß-/Kleinschreibung.
Der Nachteil ist, dass man zwei Nutzer mit E-Mail-Adressen, die sich nur in der Groß-/Kleinschreibung unterscheiden, nicht getrennt führen kann, aber das halte ich für akzeptabel.
Bei der E-Mail wurde Groß-/Kleinschreibung nicht unterschieden, aber der aus der E-Mail erzeugte Benutzername unterschied Groß-/Kleinschreibung; wenn man also ein Konto mit einer E-Mail mit Großbuchstaben anlegte, musste man diese Schreibweise exakt eingeben, um sich einzuloggen, und mit der groß-/kleinschreibungsunabhängigen E-Mail klappte der Login nicht.
Danach schaffen wir noch Sprach- und Kulturunterschiede ab; dann verschwinden Milliarden Zeilen Code, und ich höre die Repositories schon schrumpfen.
Zum Beispiel stand in einem Nutzerdatensatz JohnDoe@example.com und in einem anderen johndoe@example.com, obwohl es offensichtlich dieselbe Person war.
Noch ärgerlicher war, dass die Werte aus unterschiedlichen Systemen kamen.
Ich halte die Risikomatrix von E-Mails ohne Unterscheidung der Groß-/Kleinschreibung für deutlich besser als die von solchen mit Unterscheidung. Mit anderen Worten: Es ist richtig, alle E-Mails in Kleinbuchstaben umzuwandeln, und The Copenhagen Book liegt in diesem Punkt richtig.
Sehr gut. Mich hat schon immer gestört, dass 90 % der Sicherheitsmaterialien offenbar so gemacht sind, dass man sie nur als Sicherheitsexperte überhaupt verstehen kann. Besonders bei Kryptografie-Materialien ist das so.
Fast alle Seiten hier sind dagegen klar, knapp, auf den Punkt und direkt anwendbar, was mir gefällt.
Die Seite zu elliptischen Kurven war allerdings genauso schwer verständlich wie andere Kryptografie-Materialien.
Ich denke, die Funktionsweise selbst ist Mathematik und daher ihrem Wesen nach undurchsichtig.
Nachdem ich endliche Körper, elliptische Kurven und im Grunde Gruppen ganzer Zahlen verstanden hatte, konnte ich vieles in der Kryptografie begreifen, und meist war es in irgendeiner Form eine Variante des diskreten Logarithmusproblems.
Es wäre gut, wenn es auch alternative Dokumente zu ähnlichen Themen gäbe. Zum Beispiel etwas wie das OWASP Cheatsheet, aber aus einer praktischeren Perspektive.
Bei allem Respekt, ich bin bei diesem Dokument etwas skeptisch.
Der Name ist ziemlich hochtrabend. Das Dokument so zu nennen, als sei es von Forschern einer Universität in Copenhagen geschrieben worden, ist ein hervorragender Marketingtrick.
Lucia ist zwar eine relativ beliebte Library, aber das bedeutet nicht, dass sie Best Practices propagiert oder dass man den Autor als Autorität auf diesem wichtigen Gebiet ansehen sollte.
Es gibt auch Teile des Lucia-Designs, die mir nicht gefallen. Es wird vorgeschlagen, die Lebensdauer eines bestehenden Tokens zu verlängern, statt ein neues sicheres Token zu erstellen, wenn das Benutzer-Token kurz vor dem Ablauf steht.
Das wirkt wie ein sehr unsicheres Verhalten, weil das Token faktisch ewig lebt und weiter missbraucht werden kann; außerdem verstößt es gegen die Sicherheits-Best-Practice einer begrenzten Token-Lebensdauer.
Sowohl Lucia als auch das „Copenhagen Book“ empfehlen diesen Ansatz: https://thecopenhagenbook.com/sessions#session-lifetime
Das ist ein gängiges Verfahren und wird normalerweise Rolling Session genannt.
Das Token selbst sollte von Anfang an unveränderlich sein, seine Lebensdauer sollte also nicht verändert werden können; deshalb bedeutet Token-Erneuerung, nicht das ursprüngliche Token zu ändern, sondern ein neues Token auszugeben.
Im ersten Fall stiehlt ein Angreifer das Token und nutzt es für immer. Im zweiten Fall kann ein Angreifer, nachdem er das Token gestohlen hat, kurz vor dem Ablauf ein neues Token erhalten und sich weiterhin als der Benutzer ausgeben.
Wenn der Benutzer herausgeworfen wird, könnte er vielleicht etwas bemerken, aber die Wahrscheinlichkeit ist gering; und für eine gute User Experience braucht man ohnehin eine Karenzzeit. Andernfalls bekommen auch legitime Benutzer bei parallelen Requests Probleme.
Man kann ein zweites Token verwenden, also ein Refresh Token, aber damit verlagert man das Risiko nur auf dieses Token. Jetzt muss man sich darum sorgen, dass das Refresh Token gestohlen und dauerhaft missbraucht wird.
Refresh Tokens sind nützlich, weil man nicht bei jedem Request die Datenbank abfragen muss. Kurzlebige Session-Tokens können üblicherweise ohne Datenbank validiert werden, etwa als signierte JWTs.
Sie können bei Diebstahl aber nicht invalidiert werden und bleiben bis zum Ablauf gültig; um den Schaden zu begrenzen, muss die Ablaufzeit daher kurz sein.
Refresh Tokens hingegen fragen die Datenbank ab. Nicht das zweite Token selbst erhöht die Sicherheit, sondern die Datenbankabfrage. Denn es kann durch Löschen aus der Datenbank invalidiert werden.
Lucia fragt zumindest in den Beispielen immer die Datenbank ab, sodass das Token jederzeit invalidiert werden kann.
Um das Risiko zu verringern, sollte man Benutzern ermöglichen, aktive Sessions einzusehen und zu beenden. Wenn möglich, sollte man auch Zeit, Standort und Geräteinformationen anzeigen. Beispiel: „Gestern um 12 Uhr vormittags auf einem iPhone in Copenhagen angemeldet“
Man kann Benutzer auch benachrichtigen, wenn eine Anmeldung von einem neuen Standort oder Gerät erfolgt.
Letztlich gibt es keine Möglichkeit, langlebige Sessions vollkommen sicher zu implementieren.
Ich halte das für einen guten Punkt, würde mich aber nicht als Experten bezeichnen.
Bei OAuth gibt es zwei Dinge, die alle übersehen, und sie sind nicht offensichtlich.
Es freut mich, dass jemand eines davon anspricht. Beim Verwenden von Tokens muss man Transaktionen unbedingt als Mechanismus für verteiltes Locking einsetzen.
Bei Refresh Tokens ist das doppelt, vierfach so wichtig. Wenn dasselbe Token mehr als einmal verwendet wird, wird der Benutzer ausgeloggt.
Es spielt keine Rolle, ob das System auf einer Maschine oder auf N Maschinen läuft. Wenn zwei oder mehr Requests mit einem Refresh Token gleichzeitig laufen – was sehr häufig vorkommt –, loggt man den Benutzer aus und endet oft mit einem 500er.
Refresh Tokens sind Einweg-Tokens.
Das andere, was Entwickler und Authentifizierungs-Frameworks übersehen, ist der Parameter „state“.
Wenn man sich ansieht, wohin sich Authentifizierung heute insgesamt entwickelt, scheint es weniger um Security through Obscurity zu gehen als um Instabilität durch Unklarheit.
Wenn auch noch der Anwendungszustand hineinspielt, muss man die Anwendungslogik an die Authentifizierung anpassen, und die Anwendung muss prüfen, ob jemand das Refresh Token gestohlen hat.
Mit Transaktionen allein ist das nicht gelöst. Wenn man zum Beispiel schnell zwei Tabs öffnet, trifft man den Server zweimal mit dem ursprünglichen Refresh Token.
Es bevorzugt die Rotation von Refresh Tokens, behandelt aber auch die offensichtlichen Schwierigkeiten in Cluster-Umgebungen: https://datatracker.ietf.org/doc/html/rfc6819#section-5.2.2....
Mehrere Requests passieren immer gleichzeitig. Zum Beispiel ist es üblich, dass der Browser mit mehreren Tabs startet oder eine Smartphone-App beim Start mehrere Requests auf einmal sendet.
Ich wünschte, mehr Websites würden eine Option anbieten wie: „Lass meine Sitzung nicht ablaufen, bis ich mich abmelde; ich verstehe das Risiko.“
Heutzutage hat der „Remember me“-Button keinerlei Wirkung.
Wegen ablaufender Sitzungen wird mein Tag ständig unterbrochen. GitHub mag ich in dieser Hinsicht besonders wenig: Da ich es etwa einmal pro Woche nutze, ist die Sitzung immer abgelaufen, und dann wird auch noch Zwei-Faktor-Authentifizierung erzwungen, sodass ich jedes Mal mein Handy herausholen und eine Zahl eingeben muss.
Die User Experience ist furchtbar, aber auch wenn ich keinen Beleg dafür habe, glaube ich, dass dieses ständige Einloggen Nutzer ermüdet und sie weniger aufmerksam macht.
Wenn man sich bei einer Website mehrmals pro Woche anmeldet, ist es ungefähr beim 60. Login viel leichter, dass sich eine Phishing-Seite dazwischenschiebt. Umgekehrt wirkt es verdächtig und erhöht die Wachsamkeit, wenn ein Konto, bei dem man sich fast nie anmelden muss, plötzlich nach dem Passwort fragt.
Letztlich müssen Unternehmen lernen, dass Menschen unterschiedliche Risikobereitschaft und unterschiedliche Sicherheitslagen haben, und entsprechende Optionen anbieten.
Nebenbei: Die häufigen Sitzungsabläufe und die Zwei-Faktor-Authentifizierung bei GitHub haben mich so sehr genervt, dass ich zu Gitea gewechselt bin und das Ablaufen deaktiviert habe. Das war zu 90 % der Grund für den Umzug.
Da es nur aus meinem Netzwerk erreichbar ist, fühlt es sich sogar sicherer an. Es ist absolut möglich, dass ein Unternehmen wegen eines unflexiblen Sicherheitsmodells Kunden verliert.
Grob gesagt: Wenn die Sitzung innerhalb von 30 Tagen genutzt wurde, wird sie um weitere 30 Tage verlängert.
https://thecopenhagenbook.com/sessions#session-lifetime
Noch schlimmer ist, dass die Sitzung scheinbar etwa 1–2 Minuten länger als eine Woche hält, sodass ich diese Woche direkt nach dem Start der Arbeit von letzter Woche hinausgeworfen wurde.
Vor ein paar Wochen habe ich mich kurz vor einem wiederkehrenden Meeting angemeldet, um Notizen zu machen, und wurde dann mehrere Wochen in Folge mitten in diesem Meeting zum Login gezwungen.
Es gibt sehr viele Einstellungen, die solche „Remember me“-Buttons wirkungslos machen können.
Persönlich hatte ich, auch bei GitHub, keine Probleme damit, bei Websites eingeloggt zu bleiben.
Ich habe kürzlich vom SRP-Protokoll erfahren und bin überrascht, dass es nicht weiter verbreitet ist oder häufiger erwähnt wird.
Es ist ein relativ einfaches Protokoll, mit dem man einen Zero-Knowledge-Proof durchführen und gleichzeitig ein Sitzungstoken zwischen Server und Client erzeugen kann.
https://en.wikipedia.org/wiki/Secure_Remote_Password_protoco...
Mir gefällt dieses Material. Viele Sicherheitsempfehlungen sind schwer verständlich und wirken manchmal geradezu unsinnig. Wie ein Anwalt, der einem rät, einfach gar nichts zu tun.
Dieser Guide ist erfrischend knapp, leicht zu befolgen, gut verständlich und bietet klare Ratschläge.
Ich werde die Kommentare weiter nach Gegenmeinungen oder Vorbehalten durchsuchen, aber ich denke, ich werde ihn mit meinem Authentifizierungsprojekt abgleichen.
Ein Wunsch wäre noch ein JWT-Abschnitt. Wenn die Meinung des Autors „nicht verwenden“ lautet, wäre es schon gut, das so zu sagen.
Einer meiner häufigen Kritikpunkte an Security-Teams ist, dass sie viel Zeit damit verbringen zu sagen, was man nicht tun sollte, statt proaktiv Tools oder Wege bereitzustellen, mit denen Menschen effizient das tun können, was sie tun wollen.
E-Mail kann man als sichereres System betrachten, auf das man möglicherweise nicht sofort oder nicht von überall aus zugreifen kann.
Ich frage mich, ob „auth“ hier Authentifizierung (authn) oder Autorisierung (authz) bedeutet.
Es sieht nach Authentifizierung aus, aber eine Klarstellung wäre gut.
Eine kurze, etwas verwandte Beschwerde: eingebettete Browser machen das Web kaputt.
Eingebettete Browser machen die Nutzung von Social OAuth unmöglich. In manchen Fällen buchstäblich unmöglich, in anderen praktisch unmöglich.
Wenn man in Instagram auf einen Link tippt, öffnet er sich standardmäßig im Instagram-Browser. Wenn dieser Link „Sign in with Google“ enthält, funktioniert es nicht, weil Google „unsichere Browser“ wie Instagram blockiert.
Selbst „Sign in with Facebook“ macht Probleme, obwohl Meta sowohl Instagram als auch Facebook besitzt. Der eingebettete Browser von Facebook hat ähnliche Probleme.
Wenn man etwa in Slack auf einen Link klickt, dann auf eine Nachricht antwortet und anschließend zurück zum Browser geht in der Erwartung, dass die Seite dort noch offen ist, Slack sie aber in seinem eigenen Browser verschluckt hat und sie nirgends zu finden ist, ist das fast immer nutzlos.
Zum Glück habe ich gerade nachgesehen: In Slack gibt es eine Möglichkeit, den eingebetteten Browser zu deaktivieren.