PKCE is short for Proof Key for Code Exchange. It is a mechanism that came into being to make the use of OAuth 2.0 Authorization Code grant more secure in certain cases.
Why PKCE?
When building applications and integrating a user signing and getting access to some resource, one of the main go-to standards is OAuth 2 with the usage of the Authorization Code grant type. Those who know theĀ flow of Authz Code grant typeĀ knows that the first call(authorization request) is made through a browser(User-Agent) to obtain the authorization code. This makes the authz code susceptible to an āAuthorization Code Interception Attackā. In simple, there is a chance some on could steel that authz code(This has happened!).
Couple of ways the authz code can be stolen is by having a malicious app also register a custom URI scheme that matches the response of the Authz Code request. Or by gaining access to the HTTP request/response logs.
Well, they canāt do anything with the code as long as they donāt have the client credentials right? What if they have that too! This is why I said āā¦in certain casesā at the beginning. If your app is a mobile app or a Single Page Web App (SPA) chances are that you will be using the same client credentials for every instance of the app and the credentials are hardcoded into the apps. These are the kinds of apps that are known as a public client. Because you canāt really make sure those credentials have been kept secret and no one else already has them. For public clients, it is recommended not to perform any actions based on the availability of the client secret(by trusting the secret).
So thereās your problem if youāre having a public client and your using the Authz Code grant then some imposter could be generating and using access tokens without you even knowing!
How does PKCE prevent this?
The basic idea behind PKCE is proof of possession. The client app should give proof to the authorization server that the authz code belongs to the client app in order for the authorization server to issue an access token for the client app.
PKCE introduces few new things to the Authz Code flow; a code verifier, a code challenge and a code challenge method.Ā The ācode verifierā is a random code which meets a certain requirement. The ācode challengeā is a transformation of the code verifier or in some cases can be the code verifier itself (DO NOT use the code verifier itself!!! Please Donāt!). Use of the ācode challenge methodā is actually optional and itās used to state the method used to transform the code verifier into the code challenge and if you donāt use it an Authorization Server will assume that the code challenge and the code verifier are the same. Both the code verifier and the code challenge is created by the client app. And each pair is used only once.
So the basic flow is like this.
(A) The client sends the authorization request along with the code_challenge and the code_challenge_method.
(B) The Authorisation Server makes note of the code_challenge and the code_challenge_method and issues an authz code.
(C) The client sends an access token request along with the code_verifier.
(D) The Authorization Server validates the code_verifier with the already received code_challenge and the code_challenge_method and issues an access token if the validation is successful.
This works because the code challenge or the code verifier cannot be intercepted.Ā The code_verifier and the code_challenge should only be used once per token requesting cycle.Ā Every time an authorization request is made a new code challenge should be sent.Ā Since the code challenge is sent through the browser it is VERY important that the code challenge not be the same as the code verifier or else if by some means an attacker has access to the HTTP request; could be through HTTP logs then the use of PKCE will be useless.Ā Of course, this goes without saying the communication between the client and authorization server should be through a secured channel(TLS) so the codes cannot be intercepted.
Some basic stuff about the code_verifier, code_challenge and the code_challenge_method
code_verifierĀ ā The code verifier should be a high-entropy cryptographic random string with a minimum of 43 characters and a maximum of 128 characters. Should only use A-Z, a-z, 0ā9, ā-ā(hyphen), ā.ā (period), ā_ā(underscore), ā~ā(tilde) characters.
code_challengeĀ ā The code challenge is created by SHA256 hashing the code_verifier and base64 URL encoding the resulting hashĀ Base64UrlEncode(SHA256Hash(code_verifier). In the case that there is no such possibility ever to do the above transformation it is okay to use the code_verifier itself as the code_challenge.
code_challenge_methodĀ ā This is an optional parameter. The available values are āS256ā when using a transformed code_challenge as mentioned above. Or āplainā when the code_challenge is the same as the code_verifier. Since this is an optional parameter, if not sent in the request the Authorisation Server will assign āplainā as the default value.
Reference:Ā https://tools.ietf.org/html/rfc7636
Well, thatās it :)