Journal

Nur bestätigte Adressen: kein Login mit unbestätigter E-Mail

Seit dem 3. Oktober 2026 bekommt keine Anwendung ein EAuth-Konto mit unbestätigter Adresse. Warum, und was sich für Integrationen ändert.

Seit dem 3. Oktober 2026 gibt EAuth keiner Anwendung ein Konto, dessen E-Mail-Adresse niemand bestätigt hat. Einen Authorization Code gibt es erst, wenn die Person einen Link geöffnet hat, der an die Adresse geschickt wurde. In einem Token aus einem Login ist email_verified deshalb immer true.

Bis dahin schickte die Registrierung zwar auch einen Link, aber das Login lief weiter, ohne darauf zu warten, und das ID-Token sagte email_verified: false, bis der Link geöffnet war. Das war ehrlich und in der Praxis nicht genug. Hier steht, warum ich das geändert habe, was die Person und die Anwendung jetzt sehen und was es kostet.

Eine unbestätigte Adresse ist ein Name, den jeder eintippen kann

Jeder kann sich mit jeder Adresse registrieren. Bis der Link geöffnet ist, ist die Adresse am Konto eine Behauptung dessen, der sie eingetippt hat, keine Tatsache darüber, wer dieses Postfach liest.

OpenID Connect hat genau dafür einen Claim: email_verified ist wahr, wenn der Provider „took affirmative steps to ensure that this e-mail address was controlled by the End-User“. Die Spezifikation legt die Information ins Token. Dass jemand sie liest, kann sie nicht erzwingen. Eine Anwendung, die irgendetwas an der Adresse festmacht, ohne den Claim zu prüfen, gibt die Rechte dieser Adresse dem, der sie zuerst registriert hat:

  • Einladungen und geteilte Inhalte. Eine Anwendung, die Leute per Adresse zu einem Projekt einlädt, ein Dokument teilt oder eine Rolle vergibt, gibt das dem Konto, das diese Adresse trägt. Gehört dieses Konto jemandem, der die Adresse eines Fremden eingetippt hat, geht die Einladung an ihn.
  • Organisationen nach Domain. EAuth erlaubt einer Organisation mit verifizierter Domain, alle aufzunehmen, deren Adresse in dieser Domain liegt. Das verlangte schon bisher eine bestätigte Adresse, denn eine Adresse, die jeder eintippen kann, ist kein Beleg dafür, bei einer Firma zu arbeiten. Eine Anwendung, die auf ihrer Seite etwas Ähnliches tat, hatte keine solche Prüfung, ausser sie schrieb eine.
  • Konten, die vor ihrem Besitzer da sind. Sudhodanan und Paverd haben das als Account Pre-Hijacking untersucht: Ein Angreifer legt mit der Adresse des Opfers ein Konto an, bevor das Opfer kommt, und gelangt hinein, sobald das Opfer es nutzt. Sie fanden mindestens 35 von 75 populären Diensten, die für die eine oder andere Form davon anfällig waren.

Jede Anwendung hätte email_verified selbst prüfen können, und die meisten haben nie hingeschaut. Wird die Prüfung einmal in EAuth gemacht, hat jede Anwendung sie. Die Authentifizierungs-Richtlinien von OWASP fassen die Regel in einer Zeile: Eine E-Mail-Adresse darf als Benutzername dienen, sofern sie bei der Registrierung verifiziert wird.

Was die Person sieht

Die Registrierung schickt eine Mail mit dem Betreff „Confirm your email address for“ und dem Namen der Anwendung. Der Link funktioniert einmal, 24 Stunden lang, und trägt den Weg zurück zum Login, das die Person begonnen hat.

Kommt die Person zur Anwendung zurück, ohne ihn geöffnet zu haben, bekommt sie keinen Code, sondern eine Seite in den Farben der Anwendung: „Confirm your email address“. Darauf steht, dass die Anwendung das Konto nutzen kann, sobald die Adresse bestätigt ist, und dass der Link hierher zurückführt. Der Button „Send a new link“ öffnet die Kontoseite, die einen neuen Link schickt, der ebenfalls den Weg zurück trägt. Der Weg zurück kann nur auf eine Seite von EAuth selbst zeigen, nach derselben Regel, der ein Login beim Fortsetzen folgt. So lässt sich der Link nicht in einen Redirect irgendwohin umbauen.

Das Öffnen des Links bestätigt die Adresse sofort und zeigt „Address confirmed“ mit einem Button „Continue“, der zum Login zurückführt. Die Anwendung bekommt ihren Code, oder zuerst kommt der Zustimmungsdialog, falls die Person ihren Scopes noch nicht zugestimmt hat.

Dass beim Öffnen ohne weiteren Klick bestätigt wird, ist Absicht. Mailscanner folgen Links, und bei einer Bestätigung ist das in Ordnung: Wer Mail an die Adresse öffnen kann, ist genau die Person, um die es beim Claim geht. Ein Link zum Zurücksetzen des Passworts zeigt beim Öffnen nur ein Formular, denn den darf ein Scanner nicht verbrauchen.

Die Kontoseite schickt höchstens drei Links pro Stunde und Konto; eine vierte Anfrage sagt das und nennt den Zeitpunkt für den nächsten Versuch. Links bestehen aus 256 zufälligen Bits und werden nur als Digest gespeichert. Ein Link bestätigt nur, solange das Konto noch die Adresse hat, an die er geschickt wurde. Ein neues Passwort über einen Reset-Link zu setzen, zählt ebenfalls als Bestätigung, denn es beweist dasselbe.

Was die Anwendung sieht

  • Ein Code erst nach der Bestätigung. email_verified ist in jedem ID-Token aus einem Login true.
  • prompt=none liefert interaction_required, mit der Beschreibung „The account's email address is not confirmed yet.“ Das ist der Fehler, den OpenID Connect für eine Anfrage definiert, die ohne Anzeige einer Seite nicht abschliessen kann. Ein stilles Login, das ihn bekommt, sollte auf einen normalen Redirect zurückfallen, bei dem die Person die Bestätigungsseite sieht.
  • user.created kommt vor der Bestätigung. Der Webhook feuert bei der Registrierung mit email_verified: false, denn eine Person, die nach der Registrierung den Tab schliesst, kommt nie beim Token-Austausch an. Behandeln Sie ihn nicht als Login.
  • Single-Sign-on-Konten bestätigt der Provider. Ein Konto, das über den SAML-Provider einer Organisation entsteht, ist beim Anlegen bestätigt. Gab es ein unbestätigtes Konto mit derselben Adresse, übernimmt es die Person, für die der Provider bürgt: Passwort, Passkeys und Zwei-Faktor werden entfernt, die Refresh Tokens enden, und die Anwendung erhält session.revoked mit dem Grund „account claimed through single sign-on“.
  • Importierte Konten behalten ihr Flag. Ein Konto, das mit email_verified false importiert wurde, wird beim ersten Login mit derselben Seite angehalten und bestätigt von dort aus. Eines, das als true importiert wurde, meldet sich an wie bisher.
  • Eine korrigierte Adresse ist wieder unbestätigt. Wer die Adresse einer Person in der Konsole ändert, löscht die Bestätigung, ausser es hat sich nur die Gross- und Kleinschreibung geändert.
  • Auch ein Refresh prüft. Jedes Token, das EAuth ausstellt, auch ein erneuertes, gilt für ein Konto mit bestätigter Adresse. Das Refresh Token eines Kontos, dessen Adresse nicht mehr bestätigt ist, etwa nach einer Korrektur in der Konsole, wird mit invalid_grant abgewiesen, und die Person meldet sich neu an. Ein Access Token, das vorher ausgestellt wurde, läuft innerhalb seiner Lebensdauer ab, standardmässig 15 Minuten.

TestAnApplicationGetsOnlyConfirmedAddresses geht alles durch: registrieren, ohne Code zur Bestätigungsseite zurückkommen, ein interaction_required auf prompt=none bekommen, auf der Kontoseite einen neuen Link anfordern und prüfen, dass er sich vom ersten unterscheidet, ihn öffnen, „Continue“ mit Ziel /authorize finden und schliesslich einen Code bekommen.

Was es kostet

Ein Schritt mehr für jede neue Person, und er findet ausserhalb der Anwendung statt, in einem Postfach. Die Zustellung von Mail gehört jetzt zur Registrierung: Eine Mail, die spät ankommt, im Spam-Ordner landet oder an eine vertippte Adresse geht, hält eine Person an der Tür auf, und mehr als drei neue Links pro Stunde kann sie nicht anfordern. Manche werden dort aufgeben.

Für ein Kontosystem, auf dem andere Anwendungen aufbauen, halte ich das für den richtigen Tausch. Die Alternative war, dass jede Anwendung selbst entscheidet, ob eine Adresse etwas bedeutet, und die meisten entscheiden, indem sie nicht entscheiden. Die Regel gilt auch für unsere eigene Konsole, die sich durch dieselbe Tür anmeldet.

Quellen

  1. OpenID Connect Core 1.0: Standard Claims (email_verified) and Authentication Error Response (interaction_required), OpenID Foundation, gelesen am
  2. Authentication Cheat Sheet, OWASP, gelesen am
  3. Pre-hijacked accounts: An Empirical Study of Security Failures in User Account Creation on the Web, USENIX Security 2022, Avinash Sudhodanan and Andrew Paverd, gelesen am

Geschrieben von Samuel Krauss, Founder. Abgelegt unter eauth, openid-connect, email-verification, authentication, security, registration.

Übersetzt aus dem Englischen. Zum englischen Original

Alle Beiträge Dieser Beitrag als Markdown Atom-Feed