!!! Overview
[{$pagename}] 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.  [{$pagename}] 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").

[{$pagename}] 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|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|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.

! "how (PKCE) would mitigate the issue where the [browser-based app|Single-Page Application] can't store the client secret securely"
Because there are no [Client Secrets] using [PKCE].\\
[PKCE] works by having the [application] generate a [random] the unique string value at the beginning of the flow called a [code_verifier]. The [Application] [hashes|Hash Function] the [code_verifier] and the result is called the [code_challenge]. The [Application] then kicks off the [Authorization Code Flow], EXCEPT without the [Client Secret] but includes the [code_challenge] in the query string for the [Authorization Request] to the [Authorization Server].

!! 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.  Protocol

! 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]

! 4.3.  [OAuth Client] sends the code challenge with the [Authorization Request]
The client sends the [code_challenge] as part of the OAuth 2.0 [Authorization Request] (Section 4.1.1 of [RFC 6749].)

! 4.4. Server returns the [code|Authorization Code]
When the [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.

%%information
The exact method that the [Authorization Server] uses to associate the [code_challenge] with the issued "[code|Authorization Code]" is out of scope for this specification.
%%

4.4.1.  [Error Response|OAuth Error]
If the server requires [{$pagename}] ([PKCE]) by [OAuth Public Clients|OAuth Public Client], 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|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.

If the [code_challenge_method] from Section 4.2 was "S256", the received [code_verifier] is hashed by SHA-256, then base64url encoded, and then compared to the "code_challenge". i.e.,
%%prettify 
{{{
code_challenge = base64url.encode(crypto.createHash('sha256').update(code_verifier).digest());
}}} /%

If the "code_challenge_method" from Section 4.2 was "plain", they are  compared directly. i.e.,
%%prettify 
{{{
"code_verifier" == "code_challenge".
}}} /%
   
If the values are equal, the Access [Token_endpoint] __[MUST]__ continue processing as normal (as defined by [OAuth 2.0] [RFC 6749]).  If the values are not equal, an [error response|OAuth Error] indicating "invalid_grant" as described in section 5.2 of [RFC 6749] [MUST] be returned.

!! 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 [OAuth 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.

!! [Proof Key for Code Exchange by OAuth Public Clients] ([PKCE])
Although not part of the current [OAuth 2.0 Security Best Current Practice] ([BCP])it has been proposed to make [PKCE] [REQUIRED].

[PKCE] solves two problems: 
* stolen [authorization_codes] for [OAuth Public Clients]
* [authorization_codes] injection for all [OAuth Clients]

The section of the [OAuth 2.0 Security Best Current Practice] [BCP] (4.5.3).  Proposed Countermeasures) which says clients can do [PKCE] __or__ use the [nonce], is only talking about preventing [authorization_code] [injection|Code injection].

The [nonce] parameter solves authorization code injection if the client requests an [Id_token]. [OAuth Public Clients] using the [nonce] parameter are still susceptible to stolen [authorization_codes] so they still need to do [PKCE] as well.

The only case where [OpenID Connect] clients do not benefit from [PKCE] is if they are __also__ [OAuth Confidential Clients]. [OAuth Public Clients] (even [OIDC] clients) still need to do [PKCE] even if they check the [nonce].
   

!! More Information
There might be more information for this subject on one of the following:
[{ReferringPagesPlugin before='*' after='\n' }]