rfc-7636

Proof Key for Code Exchange by OAuth Public Clients

N. Sakimura (Editor), J. Bradley, N. Agarwal
date2015-09 streamIETF areasec wgoauth statusPROPOSED STANDARD pages20 canonicalhttps://www.rfc-editor.org/rfc/rfc7636 doi10.17487/RFC7636 errataview
OAuth 2.0 public clients utilizing the Authorization Code Grant are susceptible to the authorization code interception attack. This 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").

Extracted elements (18)

design-rationale §1

OAuth 2.0 public clients using the Authorization Code Grant are susceptible to authorization code interception attacks, where a malicious app registered with the same custom URI scheme can intercept the authorization code returned via the redirect URI and use it to obtain an access token. PKCE mitigates this by binding the authorization code to a dynamically created cryptographic secret (code_verifier) that the attacker does not possess.

oauth, security

design-rationale §7.3

Salting is intentionally omitted from the code_challenge production because the code_verifier already contains sufficient entropy (256 bits) to prevent brute-force attacks. Unlike passwords, the code_verifier's high entropy makes salt unnecessary for security, and modern GPUs can compute SHA-256 hashes faster than dictionary lookups anyway.

oauth, crypto, security

design-rationale §4.2

The 'plain' transformation method exists solely for compatibility with existing deployments and constrained environments that cannot perform SHA-256 hashing. It provides no protection against eavesdroppers who can observe the authorization request, unlike S256.

oauth, security

interoperability-note §5

Server implementations MAY accept OAuth 2.0 clients that do not implement PKCE, reverting to standard OAuth 2.0 behavior when code_verifier is absent. Clients implementing PKCE SHOULD send the additional parameters to all servers regardless of whether the server supports PKCE.

oauth

normative-requirement §4.5 REQUIRED

At the token endpoint, the client MUST send the code_verifier as an additional REQUIRED parameter along with the authorization code.

oauth

normative-requirement §4.2 MUST

If the client is capable of using 'S256', it MUST use 'S256', as 'S256' is Mandatory To Implement (MTI) on the server. Clients are permitted to use 'plain' only if they cannot support 'S256' for some technical reason and know via out-of-band configuration that the server supports 'plain'.

oauth, security

normative-requirement §4.4.1 MUST

If the server requires PKCE and the client does not send code_challenge, the authorization endpoint MUST return an error response with 'error' set to 'invalid_request'. If the server does not support the requested transformation, it MUST also return 'invalid_request'.

oauth

normative-requirement §4.3 REQUIRED

The client sends code_challenge (REQUIRED) and code_challenge_method (OPTIONAL, defaults to 'plain') as additional parameters in the OAuth 2.0 Authorization Request.

oauth

normative-requirement §4.1 SHOULD

The code_verifier SHOULD have enough entropy to make it impractical to guess. It is RECOMMENDED that a suitable random number generator produce a 32-octet sequence, which is then base64url-encoded to a 43-octet URL-safe string.

oauth, crypto, security

normative-requirement §4.6 MUST

The token endpoint MUST use the code_challenge_method bound to the authorization code to verify the code_verifier. If the computed challenge equals the stored code_challenge, processing continues normally; otherwise, the server MUST return an 'invalid_grant' error.

oauth, security

normative-requirement §4.4 MUST

When the server issues the authorization code, it MUST associate the code_challenge and code_challenge_method values with the authorization code so they can be verified later. The server MUST NOT include the code_challenge value in client requests in a form that other entities can extract.

oauth, security

protocol-element §4.2

The code_challenge is derived from the code_verifier using either the 'plain' method (code_challenge = code_verifier) or the 'S256' method (code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))). ABNF: code-challenge = 43*128unreserved.

oauth, crypto

protocol-element §4.1

The code_verifier is a high-entropy cryptographic random string using unreserved characters [A-Z]/[a-z]/[0-9]/"-"/"."/"_"/"~" with a minimum length of 43 characters and a maximum length of 128 characters, created fresh for each authorization request. ABNF: code-verifier = 43*128unreserved.

oauth, crypto

registry §6.2

This specification establishes the 'PKCE Code Challenge Methods' registry as a sub-registry of 'OAuth Parameters', using Specification Required policy. Initial entries are 'plain' and 'S256', both defined in Section 4.2 of RFC 7636.

oauth, registry

registry §6.1

Three new parameters are registered in the IANA 'OAuth Parameters' registry: code_verifier (token request), code_challenge (authorization request), and code_challenge_method (authorization request), all with change controller IESG.

oauth, registry

security-consideration §7.2 MUST NOT

Clients MUST NOT downgrade from 'S256' to 'plain' after a failure, as an error when 'S256' is presented can only mean the server is faulty or a MITM attacker is performing a downgrade attack. The 'plain' method SHOULD NOT be used in new implementations.

oauth, security

security-consideration §7.2 MUST

If code_challenge_method is 'plain' and the code_challenge is stored inside the authorization code for a stateless server, it MUST be encrypted such that only the server can decrypt it, to prevent disclosure of the code_verifier equivalent.

oauth, security

security-consideration §7.1

The code_verifier SHOULD be created with a minimum of 256 bits of entropy using a cryptographically random number generator producing a 32-octet sequence base64url-encoded. The security model relies entirely on the attacker's inability to guess or learn the code_verifier.

oauth, security, crypto