What is PKCE?
PKCE (Proof Key for Code Exchange) is an extension to the OAuth 2.0 protocol that prevents authorization code interception attacks. It is a simple, lightweight mechanism that can be implemented in any application that requests an authorization code.
Why do I need PKCE in my mobile or web app?
It all started with the OAuth 2.0 Authorization Code Grant. This grant type is used by native and web applications to obtain an access token by exchanging an authorization code for a token. The authorization code is obtained by redirecting the user to the authorization server's authorization endpoint. The authorization endpoint redirects the user back to the application with an authorization code.
The authorization code is a temporary code that the client will exchange for an access token. The authorization code is a single-use code, meaning that it can only be used once. If an attacker manages to intercept the authorization code, they can exchange it for an access token. This is a serious security issue that can result in the attacker being able to access protected resources on behalf of the user.
This attack is known as the authorization code interception attack and is described in RFC 7636. The diagram below shows the authorization code interception attack.
PKCE is an extension to the authorization code grant that prevents this type of attack. It does this by including a code challenge and code verifier in the authorization request. The authorization server will then perform a challenge-response validation to ensure that the code verifier matches the code challenge. If the validation fails, the authorization server will reject the request.
How does PKCE work?
PKCE is a simple extension to the authorization code grant. It adds two extra parameters to the authorization code grant: code_challenge
and code_verifier
. The code_challenge
is a Base64-encoded SHA-256 hash of the code_verifier
. The code_verifier
is a cryptographically random string. Both code_verifier
and the code_challenge
is generated by the client.
The code_challenge
and code_verifier
are used to perform a challenge-response validation. The authorization server will generate a code_challenge
from the code_verifier
and compare it to the code_challenge
included in the authorization request. If the two values match, the authorization server will issue an authorization token. If the two values do not match, the authorization server will reject the request.
If an attacker intercepts the authorization code, they will not be able to exchange it for an access token because they do not have the code_verifier
. The diagram below shows the authorization code interception attack with PKCE.
How do I implement PKCE?
Implementing PKCE is simple. You just need to generate a cryptographically random string and hash it using SHA-256. You can use any programming language to generate the code_verifier
and code_challenge
. The following example uses Node.js to generate the code_verifier
and code_challenge
.
const crypto = require('crypto');
const codeVerifier = crypto.randomBytes(32).toString('base64').replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
const codeChallenge = crypto.createHash('sha256').update(codeVerifier).digest('base64').replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
You can then include the code_verifier
in the authorization request. The authorization server will then perform a challenge-response validation to ensure that the code_verifier
matches the code_challenge
. If the validation fails, the authorization server will reject the request.
What is the difference between S256 and plain?
The code_challenge_method
parameter can be set to either S256
or plain
. The S256
method uses SHA-256 to generate the code_challenge
from the code_verifier
. The plain
method uses the code_verifier
directly as the code_challenge
. The S256
method is recommended because it provides a higher level of security.
How do I use PKCE with Auth0?
Auth0 supports PKCE by default. You can use PKCE with any of the Auth0 SDKs or with any OAuth 2.0 library.
How other OAuth Providers Implement PKCE?
Google, Facebook, Microsoft, GitHub, Twitter and other OAuth providers support PKCE. You can find more information about how they implement PKCE in the following articles:
Conclusion
PKCE is a simple extension to the OAuth 2.0 authorization code grant that prevents authorization code interception attacks. It is a lightweight mechanism that can be implemented in any application that requests an authorization code.
Although PKCE was originally designed for native and web applications, it is recommended that you use PKCE with all applications that request an authorization code. This includes mobile applications, desktop applications, single-page applications, and server-side applications.
Further Reading
- RFC 7636
- OAuth 2.0 for Native Apps
- OAuth 2.0 for Browser-Based Apps
- OAuth 2.0 for Mobile Apps
- OAuth 2.0 for Server-to-Server Applications
- OAuth 2.0 for Single-Page Applications
- OAuth 2.0 for Regular Web Apps
- OAuth 2.0 for Desktop Apps
- OAuth 2.0 for IoT Apps
- OAuth 2.0 for Machine-to-Machine Apps
- OAuth 2.0 for Multi-Tenant Apps
- OAuth 2.0 for Single Sign-On
- OAuth 2.0 for APIs
Thanks for reading this article. Please reach out here or on Twitter if you have any feedback or questions.