Overview#Proof Key for Code Exchange by OAuth Public Clients specification defined in RFC 7636 adds additional parameters to the OAuth 2.0 Authorization Request and Access Token Requests.
OAuth 2.0 OAuth Public Clients utilizing the Authorization Code Grant are susceptible to the authorization code interception attack. Proof Key for Code Exchange by OAuth Public Clients specification describes the attack as well as a technique to mitigate against the threat through the use of Proof Key for Code Exchange (PKCE, pronounced "pixy").
Proof Key for Code Exchange by OAuth Public Clients extension utilizes a dynamically created cryptographically random key called "code verifier".
A unique code verifier is created for every authorization Request, and its transformed value, called "code challenge", is sent to the Authorization Server to obtain the Authorization Code. The Authorization Code obtained is then sent to the Token_endpoint with the "code verifier", and the Authorization Server compares it with the previously received request code so that it can perform the Proof-of-Possession of the "code verifier" by the client. This works as the mitigation since the attacker would not know this one-time key, since it is sent over TLS and cannot be intercepted.
3. Terminology#In addition to the terms defined in OAuth 2.0 RFC 6749, this specification defines the following terms:
- code_verifier - A cryptographically random string that is used to correlate the Authorization Request to the Access Token Requests.
- code_challenge - A challenge derived from the code verifier that is sent in the Authorization Request, to be verified against later.
- Base64url Encoding - Base64 encoding using the URL- and filename-safe character set defined in Section 5 of RFC 4648, with all trailing '=' characters omitted (as permitted by Section 3.2 of RFC 4648) and without the inclusion of any line breaks, whitespace, or other additional characters.
4.1. OAuth Client creates a code verifier#The OAuth Client first creates a code_verifier, "code_verifier", for each OAuth 2.0 RFC 6749 Authorization Request
4.2. OAuth Client creates the code_challenge#The OAuth Client then creates a code_challenge derived from the code_verifier Authorization Server issues the Authorization Code in the Authorization Response, it MUST associate the code_challenge and code_challenge_method values with the Authorization Code so it can be verified later.
Typically, the code_challenge and code_challenge_method values are stored in encrypted form in the "code" itself, but could alternatively be stored on the server, associated with the code. The server MUST NOT include the code_challenge value in client requests in a form that other entities can extract.
4.4.1. Error Response#If the server requires Proof Key for Code Exchange by OAuth Public Clients (PKCE) by OAuth Public Clients, and the OAuth Client does not send the code_challenge in the request, the Authorization endpoint MUST return the authorization error response with "error" value set to "invalid_request". The "error_description" or the response of "error_uri" SHOULD explain the nature of error, e.g., code challenge required.
If the server supporting PKCE does not support the requested transform, the authorization endpoint MUST return the authorization error response with "error" value set to "invalid_request". The "error_description" or the response of "error_uri" SHOULD explain the nature of error, e.g., transform algorithm not supported.
4.5. Client sends the Authorization Code and the Code Verifier to the Token_endpoint#Upon receipt of the Authorization Code, the client sends an Access Token Request to the Token_endpoint.
4.6. Server verifies code_verifier before returning the tokens#Upon receipt of the request at the Token_endpoint, the server verifies it by calculating the code_challenge from received code_verifier and comparing it with the previously associated code_challenge, after first transforming it according to the code_challenge_method method specified by the client.
BASE64URL-ENCODE(SHA256(ASCII("code_verifier" ))) == "code_challenge"
If the "code_challenge_method" from Section 4.2 was "plain", they are compared directly. i.e.,
"code_verifier" == "code_challenge".
5. Compatibility#Server implementations of this specification MAY accept OAuth Clients that do not implement this extension. If the code_verifier is not received from the client in the Authorization Request, servers supporting backwards compatibility revert to a normal OAuth 2.0 RFC 6749 protocol.
As the OAuth 2.0 RFC 6749 server responses are unchanged by this specification, client implementations of this specification do not need to know if the server has implemented this specification or not, and SHOULD send the additional parameters as defined in Section 3. to all servers.