Teach me PKCE (Proof Key for Code Exchange) in 5 minutes

Parham
·Sep 11, 2022·

4 min read

Teach me PKCE (Proof Key for Code Exchange) in 5 minutes
Play this article

Table of contents

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 request: 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 between 43 and 128 characters in length. The code_verifier is generated by the client and the code_challenge is generated by the authorization server.

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_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.

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

Thanks for reading this article. Please reach out here or on Twitter if you have any feedback or questions.

Did you find this article valuable?

Support Parham by becoming a sponsor. Any amount is appreciated!

Learn more about Hashnode Sponsors
 
Share this