Was ist PKCE: von den grundlegenden Konzepten bis zum tiefen Verständnis
Dieser Artikel erklärt, wie PKCE (Proof Key for Code Exchange) den OAuth 2.0 Authorization Code Flow absichert, indem es verhindert, dass bösartige Anwendungen Autorisierungscodes abfangen, und führt Sie von grundlegenden Konzepten zu einem umfassenden Verständnis.
Proof Key for Code Exchange (PKCE) ist eine Erweiterung des Authorization Code Flows, die ursprünglich entwickelt wurde, um den Authorization Code Flow in mobilen Apps zu sichern. Jetzt wird es auch für Single-Page-Apps empfohlen. Ab OAuth 2.1 wird PKCE für alle Arten von Clients erzwungen, einschließlich öffentlichen Clients und vertraulichen (privaten) Clients.
In diesem Artikel helfen wir dir zu verstehen, warum PKCE erstellt wurde und wie es deine Anwendungen schützt, um dir ein tiefes Verständnis von PKCE zu geben.
Warum wird PKCE benötigt?
Im OAuth 2.0 Authorization Code Flow fordern Benutzer über eine Anwendung an, sich anzumelden. Der Authentifizierungsserver leitet Benutzer zu einer Authentifizierungsseite weiter. Nach der Benutzer-Authentifizierung gibt der Server einen Autorisierungscode an die Anwendung zurück, die diesen Code dann verwendet, um ein Zugriffstoken vom Authentifizierungsserver anzufordern.
Dieser Fluss birgt ein erhebliches Sicherheitsrisiko: Der Autorisierungscode kann von bösartigen Programmen abgefangen werden. Dies ist besonders auf mobilen Geräten besorgniserregend, wo andere Anwendungen dieselbe Umleitungs-URI registrieren und den Autorisierungscode abfangen können.
Der Abfangprozess wird im folgenden Diagramm gezeigt:
Schritt (1): Die App führt eine Auth-Anfrage über eine sichere API aus, die nicht abgefangen werden kann. In diesem Schritt gibt der Anforderer auch eine Umleitungs-URI an.
Schritt (2): Die Anfrage wird dann an den OAuth 2.0 Authorization Server weitergeleitet. Da OAuth die Verwendung von TLS erfordert, ist diese Kommunikation durch TLS geschützt und kann nicht abgefangen werden.
Schritt (3): Der Autorisierungsserver gibt den Autorisierungscode zurück.
Schritt (4.a): Der Autorisierungscode wird an den Anforderer über die in Schritt (1) angegebene Umleitungs-URI zurückgegeben. In diesem Schritt kann die bösartige App, wenn sie sich selbst als Handler für die Umleitungs-URI registriert hat, den Autorisierungscode abfangen. Mit dem Autorisierungscode kann der Angreifer in den Schritten (5.a) und (6.a) ein Zugriffstoken anfordern und erhalten.
Wie oben gezeigt, können Angreifer im OAuth 2.0 Authorization Code Flow, wenn der Autorisierungscode abgefangen wird, diesen verwenden, um Zugriffstoken zu erhalten. Daher benötigen wir einen Mechanismus, um das Abfangen von Autorisierungscodes zu verhindern, was zur Erstellung von PKCE führte.
Wie funktioniert PKCE?
Wie oben erwähnt, wenn wir einen Angriff verhindern wollen, müssen wir sicherstellen, dass nur die App, die die Anfrage initiiert hat, das Zugriffstoken anfordern und erhalten kann. Hier kommt PKCE ins Spiel.
PKCE löst dieses Problem, indem es ein Konzept für einen "Proof Key" einführt.
Wenn eine Autorisierungsanfrage gestellt wird, erzeugt die Anwendung zuerst einen zufälligen Code-Verifier und speichert ihn lokal. Dann wandelt sie diesen Code-Verifier mit spezifischen Algorithmen in eine Code-Challenge um. Die Anwendung sendet sowohl die Code-Challenge als auch die Code-Challenge Methode an den Authentifizierungsserver während der Autorisierungscode-Anfrage.
Der Code-Verifier ist eine zufällig generierte Zeichenkette, und die Code-Challenge wird durch Umwandlung des Code-Verifiers gewonnen. Zwei Umwandlungsmethoden werden unterstützt:
plain
: Verwendet den Code-Verifier direkt als Code-Challenge
S256
: Wendet eine SHA-256-Hashfunktion auf den Code-Verifier an, gefolgt von einer Base64URL-Kodierung. Da die Hash-Ausgabe nicht zurückgekehrt werden kann, um den Code-Verifier zu erhalten, und weil dieplain
-Methode bei der Übertragung anfällig für Man-in-the-Middle-Angriffe sein könnte, wird aus Sicherheitsgründen dringend empfohlen,S256
zu verwenden.
Nach der Benutzer-Authentifizierung gibt der Authentifizierungsserver den Autorisierungscode an die Anwendung zurück. Bei der Anforderung eines Zugriffstokens sendet die Anwendung sowohl den Autorisierungscode als auch den Code-Verifier an den Authentifizierungsserver. Der Server wandelt den "Code-Verifier" mit der zuvor empfangenen "Code-Challenge Methode" um und vergleicht das Ergebnis mit der zuvor empfangenen "Code-Challenge", um den Besitz des "Code-Verifiers" durch den Client zu überprüfen.
Schritt (1-3): Die App erstellt und speichert ein Geheimnis namens "Code-Verifier" und leitet eine transformierte Version "Code-Challenge" ab, die in der OAuth 2.0 Autorisierungsanfrage zusammen mit der Umwandlungsmethode "Code-Challenge Methode" gesendet wird.
Schritt (3-6): Der Auth-Server antwortet wie üblich, speichert jedoch "Code-Challenge" und die "Code-Challenge Methode".
Schritt (7.a): Die App sendet dann den Autorisierungscode an den Token-Endpoint wie üblich, enthält jedoch das in Schritt (1) generierte "Code-Verifier"-Geheimnis.
Schritt (8.a-9.a): Der Autorisierungsserver wandelt "Code-Verifier" in "Code-Challenge" um und vergleicht ihn mit "Code-Challenge" aus Schritt (1-3). Der Zugriff wird verweigert, wenn sie nicht gleich sind.
In diesem Fall, selbst wenn die bösartige App den Autorisierungscode in Schritt (6.b) abgefangen hat, ist sie nicht in der Lage, diesen für ein Zugriffstoken einzulösen, da sie nicht im Besitz des "Code_Verifier"-Geheimnisses ist, und da der "Code-Verifier" über TLS gesendet wird, kann er nicht abgefangen werden.
Zusammenfassung
In diesem Artikel wird erklärt, wie PKCE funktioniert und warum es notwendig ist, um den Authorization Code Flow zu schützen. Mit einem Proof Key-Mechanismus verhindert PKCE, dass bösartige Anwendungen Autorisierungscodes abfangen und missbrauchen. Wir hoffen, dass diese Erklärung dir hilft, PKCE in der Tiefe zu verstehen.