Public OAuth clients that use the code grant and run on smartphones are susceptible to
a code interception attack. Fortunately, this attack can be successfully prevented by
establishing a secure binding between the authorisation request and the subsequent token
The OAuth work group devised an official mini extension of the protocol for that, called
Proof Key for Code Exchange (PKCE) and published in September 2015 as RFC 7636. It is a
countermeasure against the authorization code interception attack.
How does PKCE work?
The client creates a large random string called the code verifier.
The client then computes its SHA-256 hash, called the code_challenge.
The client passes the code_challenge and code_challenge_method (a keyword for the SHA-256
hash) along with the regular authorisation request parameters to the OAuth2 server. The
server stores them until a token request is received by the client.
When the client receives the authorisation code, it makes a token request with the
code_verifier included. The OAuth2 server recomputes the code challenge, and if it matches
the original one, releases the requested tokens.
PKCE essentially works by preventing a malicious app or code that has intercepted the code (as it was passed from the system browser / the OS to the app) from exchanging it for a token.
The latest release of the light-oauth2 server adds complete support for PKCE. In order to make
use of it a public client just needs to set the appropriate PKCE request parameters. The server will take care of the rest.
We also provide the utility class CodeVerifierUtil in the light-4j utility module to assist Java clients in creating code verifiers and code challenges.
PKCE Authorization Request
An authorization request that uses PKCE goes out with
code_challenge parameter and optionally with the code_challenge_method parameter.
The value of code_challenge parameter is computed by applying a code challenge method (= computation
logic) to a code verifier.
A code verifier itself is a random string using characters of [A-Z] / [a-z] / [0-9] / “-” / “.” / “_” / “~”,
with a minimum length of 43 characters and a maximum length of 128 characters.
The defined code challenge methods are plain and S256. Respective computation logics to convert a code
verifier into a code challenge are as follows.
The plain method does not change the input, so the value of code_verifier and the resultant value
of code_challenge are equal.
The S256 method computes the SHA-256 hash of the input and then encodes the hash value using Base64-URL.
When the used code challenge method is S256, a client application must tell it by including
code_challenge_method=S256 parameter in an authorization request. When code_challenge_method parameter
is omitted, an authorization server assumes plain as the default value.
PKCE Authorization Response
After generating an authorization code, an authorization server saves it into its in-memory data grid
with the code challenge and the code challenge method contained in the authorization request.
The authorization server will use the saved code challenge and the code challenge method later to
verify a token request from the client application.
A response from the authorization endpoint has nothing special for PKCE. It’s a normal response as usual.
PKCE Token Request
After receiving an authorization code from an authorization server, a client application makes a token
request. In addition to the authorization code, the token request must include the code verifier
used to compute the code challenge.
The name of the request parameter to specify a code verifier is code_verifier.
PKCE Token Response
A token endpoint of an authorization server that supports PKCE checks whether a token request contains
a valid code verifier.
Of course, this check is performed only when grant_type is authorization_code and the authorization
code contained in the token request is associated with a code challenge.
If a token request does not contain a valid code verifier although the conditions above meet, the
request is regarded as from a malicious application and the authorization server returns an error
Verification is performed by comparing two code challenges.
One is what was contained in the authorization request and is stored in the in-memory data grid. The
other is what an authorization server computes using the code verifier contained in the token request
and the code challenge method stored in the in-memory data grid.
If the two code challenges are equal, the token request can be regarded as from the legitimate client
application that has made the original authorization request. Otherwise, the token request must be
regarded as from a malicious application.
If a token request is verified, an authorization server issues an access token as usual.