Proof Key for Code Exchange (PKCE)
PKCE stands for Proof Key for Code Exchange. It is a security extension for the OAuth 2.0 Authorization Code Flow that protects the authorization code from interception attacks. As the name suggests, PKCE is used to secure the authorization code exchange during the OAuth authentication flow.
PKCE is primarily designed for public clients such as mobile applications and single-page applications (SPAs), which cannot securely store a client secret.
Why is it needed?
In the traditional OAuth 2.0 Authorization Code Flow:
- The application requests an authorization code.
- The authorization server returns the authorization code.
- The application exchanges the authorization code for tokens using its client credentials (
client_idand optionallyclient_secret).
The Problem
In the above flow, the problem is that public clients do not have a client secret. An attacker may intercept the authorization code from the redirect URI (for example through a malicious application or browser interception) and use it to obtain tokens.
PKCE prevents this attack by binding the authorization request to the token exchange request using a one-time cryptographic secret.
How PKCE works
The following diagram illustrates the OAuth 2.0 Authorization Code Flow with PKCE.
The Client application generates code_verifier and code_challenge.
code_verifier: A secure random string known only to the client application.
code_challenge: Derived from the code_verifier. It can either be the plain value of code_verifier, or the SHA256 hash of the code_verifier encoded using Base64URL (recommended method S256).
The code_challenge is sent to the authorization server in the initial authorization request. The authorization server stores the code_challenge and later verifies it during the token exchange.
Let's understand this with an example
Imagine a scenario where:
Your application URL: https://myapp.com
Your authorization server URL: https://authserver.com
Endpoints
Authorization Endpoint: https://authserver.com/authorize
Token Endpoint: https://authserver.com/token
Redirect URI: https://myapp.com/callback
Step 1: The application generates the code_verifier and code_challenge
code_verifier dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
code_challenge BASE64URL_ENCODE(SHA256(code_verifier))
-
Example code_challenge:
E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
Step 2: Construct the authorization URL
Construct the URL with code_challenge, code_challenge_method, and other required parameters (state, nonce, client_id, etc.) and redirect the user.
Example: https://authserver.com/authorize?client_id=myclient&response_type=code&redirect_uri=https://myapp.com/callback&scope=openidprofile&state=xyz&nonce=abc&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM&code_challenge_method=S256
Step 3: Server Storage and Redirect
The authorization server stores the code_challenge and redirects the user to the application callback URL with a temporary authorization code.
This code is used to exchange tokens, but to exchange it, the client must provide the code_verifier. Therefore, even if an attacker steals the authorization code from the URL, they cannot exchange it for tokens without the correct code_verifier.
Step 4: Token Request
The client application sends a token request with the authorization code and the original code_verifier.
Step 5: Verification
The authorization server matches the code_verifier with the stored code_challenge:
BASE64URL(SHA256(code_verifier)) == stored code_challenge
If they match, the authorization server issues the tokens. Otherwise, the request is rejected.
Conclusion
PKCE is a powerful extension to the OAuth 2.0 Authorization Code Flow that significantly enhances security, especially for public clients such as mobile applications and single-page applications (SPAs).
In modern application development, PKCE is considered a best practice for all OAuth clients, including confidential clients, because it adds an extra layer of protection against authorization code interception attacks.

Top comments (0)