Before understanding the PKCE flow, I would like to introduce and explain the concept of OpenID Connect. OpenID Connect is a simple identity layer on top of the OAuth 2.0 protocol. It allows Clients to verify the identity of the end-user based on the authentication performed by an Authorization Server, as well as to obtain basic profile information about the end-user in an interoperable and REST-like manner.
PKCE stands for Proof of Key for Code Exchange and it is basically used for native mobile applications supporting operating systems for Android, iOS, etc.
Before understanding how PKCE works there are two terms which are the underlying competencies; code_verifier and code_challenge.
The client creates and records a secret named called the “code_verifier”, and derives a transformed version “t(code_verifier)” (referred to as the “code_challenge”), which is sent in the OAuth 2.0 Authorization Request along with the transformation method “t_m”.
Why PKCE for native apps?
Many of you might be thinking why PKCE for native mobile apps and not for normal web applications.
PKCE is intended for native applications because the end-user will leave the security context of the application and go to the browser to authenticate and rely on the secure return to the application from the browser. The end-user doesn’t necessarily have TLS (Transport Layer Security) on the redirect back to the application, so in the event, the authorization code goes somewhere malicious, the receiving app wouldn’t be able to get an access token without the dynamic secret.
On mobile OS, the OS allows apps to register to handle redirect URis (Uniform Resource identifier), so a malicious app can register and receive redirects with the authorization code for legitimate apps. This is known as an Authorization Code Interception Attack.
In order to prevent this Authorization Code Interception Attack, we will be using the dynamic secret that is code_verifier which is the randomly generated string. It can be different at the time of each request and the code_challenge is also used during the auth request which is the
SHA256 encrypted version of the code_verifier or equal to the code_verifier.
How PKCE mitigates this attack?
PKCE mitigates this attack by having the shared secret knowledge between the app initiating the OAuth 2.0 request and the one exchanging the code for token. In the case of the Auth Code Interception attack, the malicious app does not have the code verifier to exchange the token.
Working of PKCE
Diagram showing the PKCE flow:
- In the PKCE flow, the native application will send the auth request along with code_challenge to the system browser, and then the system browser will forward this request to the Authorization Server.
- If the authorization request is successful then the authorization server will provide the end-user with the login screen asking for the credentials to log in.
- After the successful login, the authorization server will ask for consent to the information that the relying party is going to use.
- After the end-user has successfully given the consent to the relying party the Authorization server stores the code verifier inside it.
- Then the authorization server will redirect the URi that has been registered while doing client registration along with the authorization code in the query param of the redirect URi.
- After getting the code from the authorization server the end-user will hit the token endpoint with authorization code and code_verifier (the random string that is being used to generate the code challenge). During this request, the authorization server verifies the code_verifier with the code_challenge that it has saved during the authorization request.
- After a successful request, the end-user will get the access_token and id_token from the token endpoint id_token generally identifies the identity of the user and access_token is basically used for accessing the resource server.
- After this, the access_token obtained in the above step can be used for accessing resources from the resource server. However, before giving access to the resources the resource server validates the access_token provided by the authorization server.
- After validating the access_token, if validation proves successful then the resource server will provide access.
PKCE abstract protocol flow excerpted from “Proof Key for Code Exchange by OAuth Public Clients”, RFC 7636, copyright © 2015 IETF Trust and the persons identified as document authors.
Author — Shobhit Singhal, DLT Labs™
About the Author: Shobhit Singhal is a young professional, currently working as a NodeJs & Angular developer in DL-Data Consent product team and involved in OIDC initiative from scratch. He has completed 1 year with DLT Labs recently.