8. Security Considerations (Sicherheitsüberlegungen)
8.1. Protecting the Authorization Code (Schutz des Autorisierungscodes)
Die in Abschnitt 7 dokumentierten Redirect-URI-Optionen haben den gemeinsamen Vorteil, dass nur eine native App auf demselben Gerät oder die eigene Website der App den Autorisierungscode (Authorization Code) empfangen kann, wodurch die Angriffsfläche begrenzt wird. Jedoch kann eine Code-Abfangung durch eine andere native App, die auf demselben Gerät läuft, möglich sein.
Eine Einschränkung bei der Verwendung von privat genutzten URI-Schemas (Private-Use URI Schemes) für Redirect-URIs besteht darin, dass normalerweise mehrere Apps dasselbe Schema registrieren können, wodurch unbestimmt wird, welche App den Autorisierungscode erhält. Abschnitt 1 von PKCE [RFC7636] beschreibt detailliert, wie diese Einschränkung zur Durchführung eines Code-Abfangangriffs genutzt werden kann.
Loopback-IP-basierte Redirect-URIs können auf einigen Betriebssystemen anfällig für Abfangen durch andere Apps sein, die auf dieselbe Loopback-Schnittstelle zugreifen.
Von Apps beanspruchte "https"-Schema-Redirects sind aufgrund des Vorhandenseins der URI-Autorität weniger anfällig für URI-Abfangen, aber die App ist immer noch ein öffentlicher Client (Public Client); außerdem wird die URI mit dem URI-Dispatch-Handler des Betriebssystems mit unbekannten Sicherheitseigenschaften gesendet.
Das PKCE-Protokoll [RFC7636] wurde speziell zur Eindämmung dieses Angriffs erstellt. Es handelt sich um eine Proof-of-Possession-Erweiterung (Besitznachweis-Erweiterung) für OAuth 2.0, die den Autorisierungscode vor Verwendung schützt, wenn er abgefangen wird. Um Schutz zu bieten, lässt diese Erweiterung den Client einen geheimen Verifizierer (Secret Verifier) generieren; er übergibt einen Hash dieses Verifizierers in der ursprünglichen Autorisierungsanfrage und muss (MUST) den ungehashten Verifizierer beim Einlösen des Autorisierungscodes präsentieren. Eine App, die den Autorisierungscode abgefangen hat, würde dieses Geheimnis nicht besitzen, wodurch der Code nutzlos wird.
Abschnitt 6 verlangt (MUST), dass sowohl Clients als auch Server PKCE für öffentliche native App-Clients verwenden. Autorisierungsserver (Authorization Servers) sollten (SHOULD) Autorisierungsanfragen von nativen Apps, die PKCE nicht verwenden, durch Rückgabe einer Fehlermeldung ablehnen, wie in Abschnitt 4.4.1 von PKCE [RFC7636] definiert.
8.2. OAuth Implicit Grant Authorization Flow (OAuth Implicit Grant Autorisierungsfluss)
Der OAuth 2.0 Implicit Grant Autorisierungsfluss (definiert in Abschnitt 4.2 von OAuth 2.0 [RFC6749]) funktioniert im Allgemeinen mit der Praxis, die Autorisierungsanfrage im Browser durchzuführen und die Autorisierungsantwort über URI-basierte Inter-App-Kommunikation zu empfangen. Da der Implicit Flow jedoch nicht durch PKCE [RFC7636] geschützt werden kann (was in Abschnitt 8.1 erforderlich ist), wird die Verwendung des Implicit Flow mit nativen Apps NICHT EMPFOHLEN (NOT RECOMMENDED).
Über den Implicit Flow gewährte Zugriffstoken (Access Tokens) können auch nicht ohne Benutzerinteraktion aktualisiert werden, wodurch der Authorization Code Grant Flow -- der Refresh Tokens (Aktualisierungstoken) ausstellen kann -- die praktischere Option für native App-Autorisierungen ist, die eine Aktualisierung von Zugriffstoken erfordern.
8.3. Loopback Redirect Considerations (Überlegungen zu Loopback-Redirects)
Loopback-Schnittstellen-Redirect-URIs verwenden das "http"-Schema (d.h. ohne Transport Layer Security (TLS)). Dies ist für Loopback-Schnittstellen-Redirect-URIs akzeptabel, da die HTTP-Anfrage das Gerät nie verlässt.
Clients sollten (should) den Netzwerkport nur beim Start der Autorisierungsanfrage öffnen und ihn schließen, sobald die Antwort zurückgegeben wurde.
Clients sollten (should) nur auf der Loopback-Netzwerkschnittstelle lauschen, um Interferenzen durch andere Netzwerkakteure zu vermeiden.
Während Redirect-URIs, die localhost verwenden (d.h. http://localhost:{port}/{path}), ähnlich wie die in Abschnitt 7.3 beschriebenen Loopback-IP-Redirects funktionieren, wird die Verwendung von localhost NICHT EMPFOHLEN (NOT RECOMMENDED). Die Angabe einer Redirect-URI mit dem Loopback-IP-Literal anstelle von localhost vermeidet versehentliches Lauschen auf anderen Netzwerkschnittstellen als der Loopback-Schnittstelle. Sie ist auch weniger anfällig für clientseitige Firewalls und fehlkonfigurierte Hostname-Auflösung auf dem Gerät des Benutzers.
8.4. Registration of Native App Clients (Registrierung von Native App Clients)
Außer bei Verwendung eines Mechanismus wie Dynamic Client Registration [RFC7591] zur Bereitstellung von instanzspezifischen Geheimnissen werden native Apps als öffentliche Clients klassifiziert, wie in Abschnitt 2.1 von OAuth 2.0 [RFC6749] definiert; sie müssen (MUST) als solche beim Autorisierungsserver registriert werden. Autorisierungsserver müssen (MUST) den Client-Typ in den Client-Registrierungsdetails aufzeichnen, um Anfragen entsprechend zu identifizieren und zu verarbeiten.
Autorisierungsserver müssen (MUST) von Clients verlangen, ihre vollständige Redirect-URI (einschließlich der Pfadkomponente) zu registrieren, und Autorisierungsanfragen ablehnen, die eine Redirect-URI angeben, die nicht genau mit der registrierten übereinstimmt; die Ausnahme sind Loopback-Redirects, bei denen eine genaue Übereinstimmung erforderlich ist, außer für die Port-URI-Komponente.
Für Redirects basierend auf privat genutzten URI-Schemas sollten (SHOULD) Autorisierungsserver die Anforderung in Abschnitt 7.1 durchsetzen, dass Clients Schemas verwenden, die auf umgekehrten Domainnamen basieren. Mindestens sollte (SHOULD) jedes privat genutzte URI-Schema, das kein Punkt-Zeichen (".") enthält, abgelehnt werden.
Zusätzlich zu den kollisionsresistenten Eigenschaften kann die Anforderung eines URI-Schemas, das auf einem Domainnamen basiert, der unter der Kontrolle der App steht, helfen, das Eigentum im Falle eines Streits nachzuweisen, bei dem zwei Apps dasselbe privat genutzte URI-Schema beanspruchen (wobei eine App böswillig handelt). Wenn beispielsweise zwei Apps "com.example.app" beanspruchen würden, könnte der Eigentümer von "example.com" beim App-Store-Betreiber beantragen, die gefälschte App zu entfernen. Eine solche Petition ist schwieriger zu beweisen, wenn ein generisches URI-Schema verwendet wurde.
Autorisierungsserver können (MAY) die Einbeziehung anderer plattformspezifischer Informationen anfordern, wie z.B. den App-Paket- oder Bundle-Namen oder andere Informationen, die bei der Überprüfung der Identität der aufrufenden App auf Betriebssystemen nützlich sein können, die solche Funktionen unterstützen.
8.5. Client Authentication (Client-Authentifizierung)
Geheimnisse, die statisch als Teil einer an mehrere Benutzer verteilten App enthalten sind, sollten nicht als vertrauliche Geheimnisse behandelt werden, da ein Benutzer seine Kopie überprüfen und das gemeinsame Geheimnis erfahren kann. Aus diesem Grund und den in Abschnitt 5.3.1 von [RFC6819] genannten Gründen wird es NICHT EMPFOHLEN (NOT RECOMMENDED), dass Autorisierungsserver eine Client-Authentifizierung öffentlicher nativer App-Clients unter Verwendung eines gemeinsamen Geheimnisses verlangen, da dies kaum mehr Wert bietet als die Client-Identifizierung, die bereits durch den "client_id"-Anfrageparameter bereitgestellt wird.
Autorisierungsserver, die dennoch ein statisch eingebundenes gemeinsames Geheimnis für native App-Clients verlangen, müssen (MUST) den Client als öffentlichen Client behandeln (wie in Abschnitt 2.1 von OAuth 2.0 [RFC6749] definiert) und das Geheimnis nicht als Beweis der Client-Identität akzeptieren. Ohne zusätzliche Maßnahmen unterliegen solche Clients der Client-Imitation (siehe Abschnitt 8.6).
8.6. Client Impersonation (Client-Imitation)
Wie in Abschnitt 10.2 von OAuth 2.0 [RFC6749] angegeben, sollte (SHOULD NOT) der Autorisierungsserver Autorisierungsanfragen nicht automatisch ohne Benutzerzustimmung oder -interaktion verarbeiten, außer wenn die Identität des Clients sichergestellt werden kann. Dies schließt den Fall ein, in dem der Benutzer zuvor eine Autorisierungsanfrage für eine bestimmte Client-ID genehmigt hat -- es sei denn, die Identität des Clients kann nachgewiesen werden, sollte (SHOULD) die Anfrage so verarbeitet werden, als ob keine vorherige Anfrage genehmigt worden wäre.
Maßnahmen wie beanspruchte "https"-Schema-Redirects können (MAY) von Autorisierungsservern als Identitätsnachweis akzeptiert werden. Einige Betriebssysteme können alternative plattformspezifische Identitätsfunktionen bieten, die gegebenenfalls akzeptiert werden können (MAY).
8.7. Fake External User-Agents (Gefälschte externe User-Agents)
Die native App, die die Autorisierungsanfrage initiiert, hat ein hohes Maß an Kontrolle über die Benutzeroberfläche und kann möglicherweise einen gefälschten externen User-Agent (External User-Agent) präsentieren, d.h. einen eingebetteten User-Agent (Embedded User-Agent), der als externer User-Agent erscheinen soll.
Wenn alle guten Akteure externe User-Agents verwenden, besteht der Vorteil darin, dass es Sicherheitsexperten möglich ist, schlechte Akteure zu erkennen, da jeder, der einen externen User-Agent vortäuscht, nachweislich schlecht ist. Wenn andererseits gute und schlechte Akteure gleichermaßen eingebettete User-Agents verwenden, müssen schlechte Akteure nichts vortäuschen, was sie schwerer erkennbar macht. Sobald eine bösartige App erkannt wird, kann es möglich sein, dieses Wissen zu nutzen, um die Signatur der App in Malware-Scanning-Software auf eine schwarze Liste zu setzen, Entfernungsmaßnahmen zu ergreifen (im Fall von Apps, die über App-Stores verteilt werden) und andere Schritte zur Verringerung der Auswirkungen und Verbreitung der bösartigen App zu unternehmen.
Autorisierungsserver können sich auch direkt gegen gefälschte externe User-Agents schützen, indem sie einen Authentifizierungsfaktor verlangen, der nur echten externen User-Agents zur Verfügung steht.
Benutzer, die besonders um ihre Sicherheit bei der Verwendung von In-App-Browser-Tabs besorgt sind, können auch den zusätzlichen Schritt unternehmen, die Anfrage aus dem In-App-Browser-Tab im vollständigen Browser zu öffnen und die Autorisierung dort abzuschließen, da die meisten Implementierungen des In-App-Browser-Tab-Musters eine solche Funktionalität bieten.
8.8. Malicious External User-Agents (Bösartige externe User-Agents)
Wenn eine bösartige App in der Lage ist, sich als Standard-Handler für "https"-Schema-URIs im Betriebssystem zu konfigurieren, kann sie Autorisierungsanfragen abfangen, die den Standardbrowser verwenden, und diese Vertrauensposition für bösartige Zwecke wie Phishing des Benutzers missbrauchen.
Dieser Angriff ist nicht auf OAuth beschränkt; eine bösartige App, die auf diese Weise konfiguriert ist, würde ein allgemeines und anhaltendes Risiko für den Benutzer darstellen, das über die OAuth-Nutzung durch native Apps hinausgeht. Viele Betriebssysteme mindern dieses Problem, indem sie eine explizite Benutzeraktion erfordern, um den Standard-Handler für "http"- und "https"-Schema-URIs zu ändern.
8.9. Cross-App Request Forgery Protections (Schutz vor Cross-App-Request-Forgery)
Abschnitt 5.3.5 von [RFC6819] empfiehlt die Verwendung des "state"-Parameters zur Verknüpfung von Client-Anfragen und -Antworten, um CSRF-Angriffe (Cross-Site Request Forgery) zu verhindern.
Um CSRF-ähnliche Angriffe über Inter-App-URI-Kommunikationskanäle (sogenannte "Cross-App-Request-Forgery") zu entschärfen, wird ähnlich EMPFOHLEN (RECOMMENDED), dass native Apps eine hochentropische sichere Zufallszahl im "state"-Parameter der Autorisierungsanfrage einschließen und eingehende Autorisierungsantworten ohne einen State-Wert ablehnen, der mit einer ausstehenden ausgehenden Autorisierungsanfrage übereinstimmt.
8.10. Authorization Server Mix-Up Mitigation (Eindämmung von Authorization Server Mix-Up)
Um sich gegen einen kompromittierten oder bösartigen Autorisierungsserver zu schützen, der einen anderen von derselben App verwendeten Autorisierungsserver angreift, ist es ERFORDERLICH (REQUIRED), dass eine eindeutige Redirect-URI für jeden von der App verwendeten Autorisierungsserver verwendet wird (z.B. durch Variation der Pfadkomponente) und dass Autorisierungsantworten abgelehnt werden, wenn die Redirect-URI, auf der sie empfangen wurden, nicht mit der Redirect-URI in einer ausgehenden Autorisierungsanfrage übereinstimmt.
Die native App muss (MUST) die in der Autorisierungsanfrage verwendete Redirect-URI mit den Autorisierungssitzungsdaten speichern (d.h. zusammen mit "state" und anderen verwandten Daten) und muss (MUST) überprüfen, dass die URI, auf der die Autorisierungsantwort empfangen wurde, genau übereinstimmt.
Die Anforderung von Abschnitt 8.4, insbesondere dass Autorisierungsserver Anfragen mit URIs ablehnen, die nicht mit dem Registrierten übereinstimmen, ist ebenfalls erforderlich, um solche Angriffe zu verhindern.
8.11. Non-Browser External User-Agents (Nicht-Browser externe User-Agents)
Diese Best Practice empfiehlt einen bestimmten Typ von externem User-Agent: den Browser des Benutzers. Andere externe User-Agent-Muster können ebenfalls für sicheres und benutzbares OAuth geeignet sein. Dieses Dokument macht keine Aussage zu diesen Mustern.
8.12. Embedded User-Agents (Eingebettete User-Agents)
Abschnitt 9 von OAuth 2.0 [RFC6749] dokumentiert zwei Ansätze für native Apps zur Interaktion mit dem Autorisierungsendpunkt. Diese Best Current Practice verlangt (MUST NOT), dass native Apps keine eingebetteten User-Agents verwenden, um Autorisierungsanfragen durchzuführen, und erlaubt, dass Autorisierungsendpunkte Schritte unternehmen können (MAY), um Autorisierungsanfragen in eingebetteten User-Agents zu erkennen und zu blockieren. Die Sicherheitsüberlegungen für diese Anforderungen werden hierin detailliert.
Eingebettete User-Agents sind eine alternative Methode zur Autorisierung nativer Apps. Diese eingebetteten User-Agents sind per Definition für die Verwendung durch Dritte gegenüber dem Autorisierungsserver unsicher, da die App, die den eingebetteten User-Agent hostet, auf die vollständigen Authentifizierungsdaten des Benutzers zugreifen kann, nicht nur auf die OAuth-Autorisierungsgenehmigung, die für die App vorgesehen war.
In typischen webview-basierten Implementierungen eingebetteter User-Agents kann die Host-Anwendung jeden Tastendruck aufzeichnen, der in das Login-Formular eingegeben wird, um Benutzernamen und Passwörter zu erfassen, Formulare automatisch absenden, um die Benutzerzustimmung zu umgehen, und Sitzungscookies kopieren und verwenden, um authentifizierte Aktionen als Benutzer durchzuführen.
Selbst wenn sie von vertrauenswürdigen Apps verwendet werden, die derselben Partei wie der Autorisierungsserver angehören, verletzen eingebettete User-Agents das Prinzip der geringsten Privilegien, indem sie Zugriff auf mächtigere Anmeldedaten haben, als sie benötigen, wodurch möglicherweise die Angriffsfläche vergrößert wird.
Die Ermutigung von Benutzern, Anmeldedaten in einen eingebetteten User-Agent einzugeben, ohne die übliche Adressleiste und die sichtbaren Zertifikatsvalidierungsfunktionen, die Browser haben, macht es dem Benutzer unmöglich zu wissen, ob er sich bei der legitimen Site anmeldet; selbst wenn dies der Fall ist, trainiert es sie, dass es in Ordnung ist, Anmeldedaten einzugeben, ohne zuerst die Site zu validieren.
Abgesehen von den Sicherheitsbedenken teilen eingebettete User-Agents den Authentifizierungsstatus nicht mit anderen Apps oder dem Browser, wodurch der Benutzer sich für jede Autorisierungsanfrage anmelden muss, was oft als schlechtere Benutzererfahrung angesehen wird.