Deutsch
  • Sicherheit
  • oauth
  • PKCE

Eine kurze Wiederholung der Sicherheit von OAuth

Wie gut kennen Sie die Schutzmaßnahmen, die von OAuth angewendet werden? Hält Ihr System den offenen Standard von OAuth ein? Sind Sie sich der möglichen Risiken bewusst, die bei der Implementierung des Benutzerauthentifizierungsflusses auftreten können? Lassen Sie uns kurz zusammenfassen, was wir über OAuth gelernt haben.

Simeng
Simeng
Developer

Einleitung

Vor ein paar Tagen hat uns ein interessanter Artikel über eine OAuth-Sicherheitslücke erreicht. [A-new-oauth-vulnerability-that-may-impact-hundreds-of-online-services] (https://salt.security/blog/a-new-oauth-vulnerability-that-may-impact-hundreds-of-online-services) vom SALT-Labor. Dieser spezielle Beitrag hebt eine Schwachstelle hervor, die in [Expo] (https://expo.dev/), einem weit verbreiteten Framework zur Implementierung von OAuth und anderen Funktionen, entdeckt wurde. Es behandelt speziell eine Schwachstelle in der Expo-Auth-Session-Bibliothek, die bereits zugewiesen und ordnungsgemäß behoben wurde.

Wenn Sie sich für OAuth interessieren oder wie wir an einem CIAM-bezogenen Produkt arbeiten, empfehlen wir Ihnen dringend, diesen Artikel zu lesen. Er ist sehr inspirierend und bietet hilfreiche Einblicke. Diese Berichte von White-Hat-Hackern erinnern uns daran, wie selbst das einfachste Feature Schwachstellen verursachen kann. Wenn es um Cybersicherheit und Autorisierung geht, können wir nie zu vorsichtig sein, um die Sicherheit und Privatsphäre der Benutzerinformationen zu gewährleisten. Wenn dieser Artikel Ihre Aufmerksamkeit erregt, bin ich sicher, dass Sie uns zustimmen werden.

Es erinnert mich an die Zeit, als wir gerade erst angefangen hatten. Wir haben viel Zeit damit verbracht, die Details der OAuth- und OIDC-Protokolle zu lernen und zu erforschen. Es war schmerzhaft und mühsam, aber der Nutzen war immens. Auch wenn vielleicht nicht jeder in unserem Team ein OAuth-Experte ist, ist doch jeder bemüht, kontinuierliche Anstrengungen für Sicherheit und Genauigkeit zu unternehmen. Durch diese engagierten Bemühungen hat sich das Logto-Produkt zu dem entwickelt, was es heute ist.

Ein großes Dankeschön an diese großartige Gelegenheit, wir möchten gerne unser Gedächtnis bezüglich einiger Sicherheitsdetails von OAuth auffrischen.

Ein Blick auf den OAuth-Autorisierungscode-Flow

[OAuth 2.0] (https://datatracker.ietf.org/doc/html/rfc6749#section-1.3.1) bietet verschiedene Autorisierungsflüsse, die auf verschiedene Client-Typen und Anforderungen zugeschnitten sind. Dazu gehören der [Implicit Flow] (https://datatracker.ietf.org/doc/html/rfc6749#section-4.2), [Client Credentials Flow] (https://datatracker.ietf.org/doc/html/rfc6749#section-4.4), [Resource Owner Password Credentials Flow] (https://datatracker.ietf.org/doc/html/rfc6749#section-4.3), und [Device Authorization Flow] (https://www.rfc-editor.org/rfc/rfc8628). Der Authorization Code Flow jedoch sticht als der sicherste und am weitesten verbreitete hervor. Im Gegensatz zu anderen Flows trennt er die Benutzerauthentifizierung von der Client-Anwendung und beinhaltet den Austausch eines Autorisierungscodes gegen Tokens. Dieser Ansatz bietet eine zusätzliche Ebene der Sicherheit, da die sensiblen Tokens nie dem Client ausgesetzt sind. Darüber hinaus unterstützt der Authorization Code Flow die serverseitige Token-Verwaltung, was ihn für Webanwendungen, die robuste Sicherheit und verbesserte Kontrolle über den Benutzerzugriff erfordern, geeignet macht.

Hier ist ein einfaches [Authorization Code Flow] (https://datatracker.ietf.org/doc/html/rfc6749#section-1.3.1) Diagramm:

Lassen Sie uns einen Blick auf die beiden wichtigsten Anfragen werfen, die im Authorization Code Grant-Flow gemacht werden, und die scheinbar trivialen Fragmente darin, die aber eine entscheidende Rolle beim Schutz vor Betrug spielen.

Die Autorisierungsendpunkt:

Der Token-Austausch-Endpunkt:

Client-Anmeldeinformationen

In OAuth beziehen sich [Client-Anmeldeinformationen] (https://datatracker.ietf.org/doc/html/rfc6749#section-1.3.4) auf die Anmeldeinformationen, die eine Client-Anwendung verwendet, um sich bei dem Autorisierungsserver zu authentifizieren und sich zu identifizieren. Diese Anmeldeinformationen werden während des Client-Registrierungsprozesses erhalten und dienen der Validierung der Identität des Clients bei Anfragen an den Autorisierungsserver. (Sie können Ihre Client-Anmeldeinformationen in der Admin-Konsole von Logto finden, wenn Sie Ihre Anwendung erstmalig registriert haben.)

Die Client-Anmeldeinformationen bestehen typischerweise aus zwei Komponenten:

  1. Client-ID: Eine eindeutige Kennung, die der Client-Anwendung vom Autorisierungsserver zugewiesen wurde. Es handelt sich um einen öffentlichen Wert, der allgemein nicht als sensibel betrachtet wird.
  2. Client Secret: Ein vertraulicher und sicher gespeicherter Wert, der nur dem Client und dem Autorisierungsserver bekannt ist. Es dient als eine Form der Authentifizierung für die Client-Anwendung und wird verwendet, um die Identität des Clients bei Anfragen an den Autorisierungsserver zu überprüfen.

Wie Sie vielleicht feststellen, wird die Kombination aus Client-ID und Client Secret während der Token-Anfrage verwendet, um den Client zu authentifizieren und Zugriffstoken zu erhalten.

Die Client-Anmeldeinformationen spielen eine entscheidende Rolle bei der Gewährleistung der Sicherheit des OAuth-Flows. Sie helfen dem Autorisierungsserver, die Authentizität von Client-Anwendungen zu überprüfen und den Zugriff auf geschützte Ressourcen zu kontrollieren. Es ist wichtig, die Client-Anmeldeinformationen sicher zu behandeln und sie vor unberechtigtem Zugriff zu schützen. Logto kategorisiert die Client-Anwendungen nach zwei verschiedenen Sicherheitsstufen:

  • Vertrauliche Clients: Hierzu gehören serverseitig gerenderte Webanwendungen und Maschine-zu-Maschine (M2M)-Anwendungen. Im Falle vertraulicher Clients werden alle autorisierungsbezogenen Anmeldeinformationen, einschließlich der Client-Anmeldeinformationen, sicher auf der Serverseite gespeichert. Außerdem werden alle zwischenliegenden Austauschanfragen verschlüsselt, um die Vertraulichkeit der Daten zu gewährleisten. Das Risiko eines Lecks von Client-Anmeldeinformationen für vertrauliche Clients ist sehr gering, was sie von Natur aus sicherer macht. Daher werden vertrauliche Clients standardmäßig mit einem höheren Sicherheitslevel behandelt. Im Token-Austausch-Flow ist die Vorstellung des Client Secret ein MUSS.
  • Öffentliche Clients: Hierzu gehören Einzelseiten-Webanwendungen (SPA) und native Anwendungen. Bei öffentlichen Clients werden die Client-Anmeldeinformationen normalerweise auf der Client-Seite hart codiert, etwa innerhalb eines JavaScript-Pakets oder eines App-Pakets auf einer nativen Plattform. Das Risiko eines Anmeldeinformationslecks ist im Vergleich zu vertraulichen Clients höher, da die Client-Anmeldeinformationen im Client-seitigen Code inhärent ausgesetzt sind. Im Token-Austausch-Flow ist die Vorstellung von Client Secret OPTIONAL. Logto vertraut standardmäßig diesen Anmeldeinformationen von einem öffentlichen Client nicht.

State

Im OAuth-Flow ist das state-Parameter ein zufällig generierter Wert, der in die Autorisierungsanfrage aufgenommen wird, die der Client an den Autorisierungsserver sendet. Sein Zweck besteht darin, den Zustand oder Kontext der Anfrage des Clients während des Autorisierungsprozesses aufrechtzuerhalten.

Das state-Parameter fungiert als Sicherheitsmaßnahme, um [Cross-Site-Request-Fälschung (CSRF)] (https://datatracker.ietf.org/doc/html/rfc6749#section-10.12) Attacken zu verhindern. Wenn der Autorisierungsserver den Benutzer nach Authentifizierung und Autorisierung zurück zur Client-Anwendung leitet, schließt er denselben state-Wert in die Antwort ein. Die Client-Anwendung MUSS diesen Wert mit dem ursprünglichen state-Wert vergleichen, den sie in der Autorisierungsanfrage gesendet hatte.

Durch die Prüfung des state-Parameters kann der Client sicherstellen, dass die Antwort, die er vom Autorisierungsserver erhält, der ursprünglichen Anfrage entspricht, die er gestellt hat. Dies hilft, Angriffe zu verhindern, bei denen ein Angreifer versucht, den Client dazu zu bringen, eine für einen anderen Benutzer oder eine andere Anwendung bestimmte Antwort anzunehmen.

Nehmen Sie das folgende Beispiel für einen CSRF-Angriff in einem fiktiven Anwendungsfall:

CSRF-Angriff: Betrug zur Bindung des Social-Accounts - Problem

Mit einem richtigen State-Validierungsmechanismus kann der Client den Angriff erkennen und verhindern, dass der Benutzer auf die Website des Angreifers umgeleitet wird:

CSRF-Angriff: Betrug zur Bindung des Social-Accounts - Lösung

PKCE

Wie bereits erwähnt, tragen öffentliche Clients wie SPA-Web-Apps und native Anwendungen ein höheres Risiko für ein Auth-Anmeldeinformationsleck, einschließlich des vom Autorisierungsserver ausgestellten Autorisierungscodes.

PKCE steht für [Proof Key for Code Exchange] (https://datatracker.ietf.org/doc/html/rfc7636). Es handelt sich dabei um eine Erweiterung des OAuth 2.0 [Authorization Code Flow] (https://datatracker.ietf.org/doc/html/rfc6749#section-1.3.1), die die Sicherheit von öffentlichen Clients verbessert.

PKCE wurde eingeführt, um das Risiko zu mindern, dass ein Angreifer den Autorisierungscode abfängt und diesen ohne Wissen des Clients gegen ein Zugriffstoken austauscht. Diese Art von Angriff, bekannt als ein Autorisierungscode-Abfangangriff, ist in Umgebungen häufiger, in denen die Client-Anwendung ein Client Secret nicht sicher speichern kann.

Um PKCE zu implementieren, generiert die Client-Anwendung einen zufälligen Code Verifier und leitet daraus eine Code Challenge ab, indem sie einen bestimmten Hashing-Algorithmus (normalerweise SHA-256) verwendet. Die Code Challenge wird in die anfängliche Autorisierungsanfrage aufgenommen, die an den Autorisierungsserver gesendet wird.

Wenn der Autorisierungsserver den Autorisierungscode ausstellt, enthält die Client-Anwendung den ursprünglichen Code Verifier in der Token-Anfrage. Der Server überprüft, dass der Code Verifier mit der gespeicherten Code Challenge übereinstimmt, und gibt erst dann das Zugriffstoken aus.

Durch die Verwendung von PKCE stellt die Client-Anwendung sicher, dass der Autorisierungscode allein nicht ausreicht, um ein Zugriffstoken zu erhalten. Dieser Mechanismus fügt dem Autorisierungsablauf eine zusätzliche Sicherheitsebene hinzu, insbesondere für öffentliche Clients, bei denen die Speicherung von Client Secrets herausfordernd ist.

Logto verwendet PKCE als den EINZIGEN Autorisierungsflow für alle Anwendungen vom Typ öffentlicher Client. Allerdings kann PKCE für die vertraulichen Clients weggelassen werden.

Redirect URI

Eine [Redirect URI (Uniform Resource Identifier)] (https://datatracker.ietf.org/doc/html/rfc6749#section-3.1.2) ist ein spezifischer Endpunkt oder URL, zu dem der Autorisierungsserver den Benutzer nach dem Authentifizierungs- und Autorisierungsprozess in OAuth zurückleitet.

Während des OAuth-Flows schließt die Client-Anwendung eine Redirect URI als Teil der anfänglichen Autorisierungsanfrage ein. Diese URI dient als Callback-URL, zu der der Benutzer nach erfolgreicher Authentifizierung und Erteilung von Berechtigungen für den Client weitergeleitet wird.

Sobald der Benutzer den Authentifizierungsprozess abgeschlossen hat, generiert der Autorisierungsserver eine Antwort, die einen Autorisierungscode enthält, und leitet den Benutzer zurück zur angegebenen Redirect URI.

Die Validierung der Redirect URI ist ein wesentlicher Schritt zur Gewährleistung der Sicherheit und Integrität des OAuth-Flows. Dabei wird überprüft, ob die in der Autorisierungsanfrage und den nachfolgenden Weiterleitungen verwendete Redirect URI gültig und vertrauenswürdig ist.

Lassen Sie uns zurückgehen und einen Blick auf den ursprünglichen [OAuth-Schwachstellenbericht] (https://salt.security/blog/a-new-oauth-vulnerability-that-may-impact-hundreds-of-online-services) werfen. (Der folgende Abschnitt ist aus dem ursprünglichen [Post] (https://salt.security/blog/a-new-oauth-vulnerability-that-may-impact-hundreds-of-online-services) entnommen)

When the user clicks “login with facebook” using the Mobile APP in Expo Go, it redirects to the user to the following link:

https://auth.expo.io/@moreisless3/me321/start?authUrl=https://www.facebook.com/v6.0/dialog/oauth?code_challenge=...&display=popup&auth_nonce=...&code_challenge_method=S256&redirect_uri=https://auth.expo.io/@moreisless3/me321&client_id=3287341734837076&response_type=code,token&state=gBpzi0quEg&scope=public_profile,email&returnUrl=exp://192.168.14.41:19000/--/expo-auth-session

In the response, auth.expo.io set the following cookie: ru=exp://192.168.14.41:19000/--/expo-auth-session. The value RU will be later used as a Return Url in step 5. It then shows the user a confirmation message, and if the user approves - it redirects him to the Facebook login to continue the authentication flow

This page reads the query parameter “returnUrl” and sets the cookie accordingly.

Let’s change the returnUrl to hTTps://attacker.com (https is not allowed, so I tried to insert capitals letters and it worked), which sets the RU (Return Url)in the cookie to https://attacker.com.

Im obigen Fall hat Expo außer Acht gelassen, dass die ursprünglichen redirect_uri-Parameter einen neuen Parameter namens returnUrl ohne ordnungsgemäße Validierung eingeführt haben. Diese Nachlässigkeit bot Angreifern die Möglichkeit, auf den von Facebook zurückgegebenen Autorisierungscode zuzugreifen. Details finden Sie im ursprünglichen [Post] (https://salt.security/blog/a-new-oauth-vulnerability-that-may-impact-hundreds-of-online-services).

Die Validierung der Redirect URI dient mehreren wichtigen Zwecken:

  1. Verhinderung von Phishing-Angriffen: Durch die Validierung der Redirect URI stellt der Autorisierungsserver sicher, dass der Benutzer zu einem vertrauenswürdigen und autorisierten Endpunkt zurückgeleitet wird. Dies hilft, zu verhindern, dass Angreifer Benutzer zu schädlichen oder nicht autorisierten Orten umleiten.
  2. Schutz vor offenen Weiterleitungen: Offene Weiterleitungen sind Schwachstellen, die ausgenutzt werden können, um Benutzer zu bösartigen Websites umzuleiten. Durch die Validierung der Redirect URI kann der Autorisierungsserver sicherstellen, dass die Weiterleitung innerhalb der Grenzen der autorisierten Domain oder des Satzes von vertrauenswürdigen Domains bleibt.
  3. Gewährleistung der korrekten Weiterleitung von Autorisierungsantworten: Durch die Validierung der Redirect URI wird sichergestellt, dass der Autorisierungsserver den Benutzer zur beabsichtigten Client-Anwendung zurückleitet. Sie sorgt dafür, dass die Antwort, wie ein Autorisierungscode oder ein Zugriffstoken, an das richtige Ziel geliefert wird.

In Logto ist die Registrierung von redirect_uri für alle Arten von Anwendungen obligatorisch. Wir vergleichen und passen den empfangenen Wert gegen die in Logto-Server registrierten an. Dazu gehören auch benutzerdefinierte Suchparameter. Wenn eine Autorisierungsanfrage aufgrund eines fehlenden, ungültigen oder nicht übereinstimmenden redirect_uri-Wertes die Validierung nicht besteht, wird ein Fehler wegen ungültiger Redirect URI an die registrierte redirect_uri auf Datei zurückgegeben.

Zusammenfassung

Aufgrund ihrer komplizierten und nuancierten Natur ist es verständlich, dass diese Details oft übersehen werden. Einige sind nur eine zufällige Zeichenkette wie state.

Es ist jedoch wichtig zu wissen, dass diese Sicherheitsmaßnahmen zusätzliche Schutzschichten für die Benutzerautorisierung hinzufügen, die Risiken wie CSRF-Angriffe, das Abfangen von Autorisierungscodes und nicht autorisierte Umleitungen mindern.

Dies sind nur ein kleiner Teil der umfassenden Sicherheitsfunktionen, die das OAuth-Protokoll bietet. OAuth bietet ein robustes Framework für sichere Authentifizierung und Autorisierung. Es bietet auch flexible und offene Endpunkte, um verschiedene Anforderungen in realen Produktanwendungen zu erfüllen.

Als Entwickler und Diensteanbieter ist es unerlässlich, kontinuierlich die Sicherheit des Benutzerautorisierungsflusses zu priorisieren. Es ist wichtig, stets wachsam zu sein, Best Practices einzuhalten und auf dem Laufenden zu bleiben mit den neuesten Entwicklungen im OAuth-Ökosystem, um die Integrität und den Schutz von Benutzeridentitäten und sensiblen Daten zu gewährleisten. Wir werden uns weiterhin dafür einsetzen, die höchsten Sicherheitsstandards in der Implementierung von OAuth einzuhalten und die Privatsphäre und das Vertrauen unserer Benutzer zu schützen.