OAuth-Callback sicher? Redirect-URIs, PKCE und Login-Zustand prüfen
Ein funktionierender Google-, Microsoft- oder SSO-Login beweist keine sichere OAuth/OIDC-Integration. Prüfen Sie Redirect-URIs, PKCE, state/nonce, Issuer-Bindung und Preview-Umgebungen.
Der Login funktioniert: Der Identity Provider schickt den Browser zurück, die Anwendung tauscht einen Code und erstellt eine Session. Funktional ist damit alles grün. Sicherheitstechnisch ist die wichtigere Frage aber: Akzeptiert der Callback nur die Antwort, die exakt zu diesem gestarteten Login gehört?
RFC 9700, die aktuelle OAuth 2.0 Security Best Current Practice, behandelt Redirect-Flows bewusst streng. Redirect-URIs sollen exakt mit vorregistrierten Werten verglichen werden, offene Redirectoren gehören weder in Client noch Autorisierungsserver, PKCE ist für öffentliche Clients Pflicht und auch für vertrauliche Clients empfohlen. Bei mehreren Identity Providern muss außerdem klar sein, welcher Autorisierungsserver die Antwort wirklich ausgestellt hat.
1. Redirect-URIs sind keine bequeme Wildcard-Zone
Konfigurationen wie https://*.example.de/auth/callback, https://example.de/* oder „alle Preview-URLs unseres Hosters“ wirken praktisch. Sie vergrößern aber die Vertrauenszone.
RFC 9700 fordert exakten Stringvergleich für registrierte Redirect-URIs. Die relevante Ausnahme betrifft variable Ports bei localhost-Redirects nativer Apps. Für normale Webanwendungen gilt: Registrieren Sie konkrete HTTPS-Callback-URLs statt breiter Muster.
Das wird besonders bei Preview-Deployments wichtig. Ein saubereres Modell trennt Produktion, Staging und Vorschau-Umgebungen in eigene OAuth-Clients oder nutzt für Previews einen stabilen, serverseitig kontrollierten Test-Callback. Kurzlebige PR-Domains sollten nicht automatisch dieselbe Authentifizierungsgrenze wie Produktion erhalten.
2. Der Callback darf kein Open Redirect sein
Viele Anwendungen speichern ein Rücksprungziel in returnTo, next oder continue. Das ist normal. Problematisch wird es, wenn nach erfolgreichem Login ungeprüft auf eine beliebige URL weitergeleitet wird.
RFC 9700 verbietet offene Redirectoren bei OAuth-Clients und Autorisierungsservern. Ein sicherer Ansatz bindet das Ziel vor Beginn des Logins an die Transaktion und erlaubt beispielsweise nur relative Pfade oder explizit freigegebene Origins.
Prüfen Sie deshalb, ob Werte wie https://evil.example, //evil.example oder URL-Parsing-Tricks als Post-Login-Ziel abgewiesen werden.
3. PKCE ist auch für Webanwendungen relevant
PKCE wurde ursprünglich für öffentliche Clients entworfen. RFC 9700 geht heute weiter: Öffentliche Clients müssen PKCE nutzen; für vertrauliche Clients wird es empfohlen. Die Empfehlung gilt ausdrücklich auch für Webanwendungen.
Der Client erzeugt pro Login einen zufälligen code_verifier, leitet daraus eine code_challenge ab und sendet diese mit dem Autorisierungsrequest. Beim Code-Austausch muss der passende Verifier vorliegen. Ein abgefangener Autorisierungscode allein genügt dann nicht.
RFC 9700 empfiehlt Challenge-Methoden, die den Verifier nicht im Autorisierungsrequest offenlegen; aktuell ist S256 die entsprechende Methode. Challenge und Verifier müssen transaktionsspezifisch sein. Ein konstanter Wert ist kein sinnvoller PKCE-Schutz.
4. state und nonce müssen geprüft werden, nicht nur existieren
Eine Library kann state und nonce automatisch erzeugen. Entscheidend ist, ob der Callback sie tatsächlich gegen die gestartete Transaktion validiert.
RFC 9700 verlangt Schutz gegen fremde oder manipulierte Callback-Requests. Je nach Flow kann PKCE dafür eine Rolle spielen; bei OpenID Connect kommt nonce hinzu, andernfalls werden einmalige, an Browser und Transaktion gebundene CSRF-Token über state verwendet.
Red Flags sind:
statewird erzeugt, aber nicht verglichen,- Werte bleiben nach erfolgreichem Login wiederverwendbar,
- parallele Login-Versuche überschreiben sich,
noncewird nicht gegen das ID Token geprüft,- Rücksprungziele werden ungeschützt in clientseitigen Zustand gepackt.
Der Callback sollte nicht fragen „Ist ein Wert vorhanden?“, sondern „Gehört dieser exakte Wert zu einer noch offenen Transaktion dieses Browsers?“
5. Mehrere Provider brauchen eine eindeutige Issuer-Bindung
Sobald eine Anwendung Google, Microsoft und vielleicht ein Unternehmens-SSO anbietet, spricht sie mit mehreren Autorisierungsservern. Dann muss sie erkennen, welcher Provider die Antwort ausgestellt hat.
RFC 9700 fordert Schutz gegen Mix-up-Angriffe. RFC 9207 definiert dafür den iss-Parameter in Autorisierungsantworten. Der Client kann ihn mit dem für die Transaktion erwarteten Issuer vergleichen. OpenID Connect liefert ebenfalls Issuer-Informationen über das ID Token.
Ein Code von Provider A darf niemals versehentlich an den Token-Endpunkt von Provider B geschickt werden. Token-, JWKS- und UserInfo-Endpunkte sollten aus vertrauenswürdiger Provider-Metadatenkonfiguration stammen, nicht aus frei manipulierbaren Request-Werten.
6. Ein Token ist erst nach Validierung eine Identität
Bei OpenID Connect reicht es nicht, dass der Token-Endpunkt JSON zurückgibt. Bevor daraus eine lokale Sitzung entsteht, müssen die für den Flow erforderlichen Eigenschaften geprüft werden: unter anderem Signatur, erwarteter Issuer, Audience beziehungsweise Client-ID, Zeitgültigkeit und nonce.
Eine etablierte Auth-Library kann vieles korrekt übernehmen. Ein Audit sollte aber kontrollieren, ob sie aktuell und richtig konfiguriert ist und ob eigener Glue-Code zentrale Validierung umgeht.
Praktischer Callback-Audit
Inventarisieren Sie für jeden Provider Client-ID, Umgebung, Redirect- und Logout-URIs, verwendete Library und Metadatenquelle. Suchen Sie ausdrücklich nach alten Staging- oder Preview-Callbacks.
Testen Sie danach negativ: andere Subdomain, anderer Pfad, anderer Port, http statt https, alte Preview-Domain und ähnlich aussehende Hostnamen sollten nicht akzeptiert werden.
Starten Sie zwei Login-Flows parallel, verändern Sie state, spielen Sie einen alten Callback erneut ab und prüfen Sie, ob Codes oder Transaktionswerte wiederverwendbar sind. Bei mehreren Providern testen Sie zusätzlich, ob jede Antwort an den erwarteten Issuer gebunden bleibt.
Was Website-Pflichtencheck prüfen würde
Ein OAuth/OIDC-Check kann registrierte Redirect- und Logout-URIs, Wildcards und alte Preview-Ziele, HTTPS und exaktes Redirect-Matching, PKCE mit S256, state-/nonce-Validierung, offene Redirects, Trennung von Produktion und Testumgebungen, Provider-/Issuer-Bindung, OIDC-Tokenvalidierung sowie Fehlerpfade auf Code- oder Token-Leaks untersuchen.
Das Ziel ist nicht, OAuth selbst neu zu bauen. Je weniger Sonderlogik zwischen Provider, gepflegter Protokoll-Library und lokaler Session liegt, desto verständlicher und testbarer wird die Sicherheitsgrenze.
Ein Login, der funktioniert, ist ein Funktionstest. Ein Login, der nur die exakt gestartete Transaktion, den erwarteten Provider und das erlaubte Rücksprungziel akzeptiert, ist eine belastbarere Architektur.