Mitigating Code Interception Attack Using PKCE

Rohit Pandey
Secure Your Apps
Published in
4 min readJul 18, 2021

--

Implementation of PKCE has recently gained lot of attraction, as now we have lot more Mobile Applications out there for Android and IOS devices. With the extensive use of devices like Tablet this has become much needed.

RFC 7636 talks about Code Interception attacks .

https://datatracker.ietf.org/doc/html/rfc7636

In this blog we will take a deep dive on the PKCE implementation.

Login flow for native applications using PKCE along with Oauth2.0

So, basically it comprises of 7 step process , which finally gives the Native app relevant access_token in order to access the Enterprise API.

Step 1) From Native app, user clicks on the application icon and as application has to first authenticate the user, it will trigger the Oauth flow, and for the same it will spin up the system browser to initiate the login flow.

code_verifier:- Interesting thing here is that native mobile application before redirecting the user to Auth server , generates a random value which is technically called as “code_verifier”. As per standards, this random value can be in the range 43 to 128 characters.

code_challenge:- Native app calculates the SHA256 of the code verifier and finds it’s base 64 URL encoded representation with no padding.

Note:- code_verifier is send with the /oauth_token endpoint call while code_challenge and code_challenge_method is send during /authorize call.

Sample request:- <Auth_server_url>/authorize?client_id=”xxx”&response_type=”code”&code_challenge=”N2E2MmIwMzU5ZDljOTk5NzBlOTY2NmQ5ZDBkNjcxNWVlMDFkMGYxODhhMGY4ZjI1ZDkzMjJmY2Y5ZTA1NGFlNw”&code_challenge_method=”S256"

Step 2 ) As the system browser doesn’t have the session for the login request , it will redirect the user to the /authorize endpoint of the Authorization Server along with all the query args presented to it by native app.

Step 3) Authorization server on receiving the request, redirects the user to the login page where she/he provides her/his credentials.

Step 4) Once user authenticity is validated Auth Server issues the auth_code and keeps a track of the code_challenge against the issued auth_code. There are some Auth servers that also embed the code_challenge to code.

Step 5) System Browser shares the auth_code to Native App, which has actually triggered the Oauth flow.

Step 6) Native App now triggers the token acquisition flow wherein it has to pass the code_verifier along with the request. Auth server internally takes the SHA256 hash of the code_verifier , followed by Base 64 URL encoding(lets call it X) and checks whether the authcode is valid and also if the value X is similar as that of code_challenge that was passed in the /authorize flow.

Step 7) Access the target API.

Why we need PKCE?

Lets consider that in your native device you have installed a malicious app, which some how can read the http request being made to system browser(and also has client credentials of your native app which it uses for authorization_grant type flow), then captures the auth_code in its internal memory , and before the legitimate app triggers the token acquisition, this malicious app retrieves the access token, as Auth Server founds the client credentials to be valid and along with the auth_code shared , it has no further mechanism to confirm the authenticity of the client.

With PKCE coming in picture , this malicious app has to also share the code_verifier during the oauth/token request, which it cannot obtain, and hence Auth server can immediately differentiate as client is compromised.

When a system is under this kind of attack user might experience login failures as when their native app tries to exchange the access token from auth_code, Auth server gives error as one auth_code can be used only once. Also, the malicious app has to be very fast as most of the systems auth_code are valid only for 1 min. For better security as per standards, auth_code should be valid only for extremely small duration.

What Authorization Server should do when system is under Code Interception Attack?

First of all having PKCE implementation is must to have feature, which eventually ensures that even if your device is compromised , malicious app cannot get the access token, but at the same time when Auth server gets a request with valid auth_code but improper code_verifier, it can take a call as to even deactivate the oauth client and there should be some mechanism to notify the app owners that your client has been compromised, on device with IP Address. They can also black list the ip address from the API Gateway so that all interactions from the compromised device can be made impossible.

Now you all might be thinking that this is fine but what will happen if we are operating from native devices which don’t have system browser support?

I will be detailing out the implementation for this use case also in next part.

--

--