idnits 2.17.1 draft-ietf-oauth-spop-15.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- No issues found here. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year -- The document date (July 8, 2015) is 3215 days in the past. Is this intentional? Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) == Missing Reference: 'A-Z' is mentioned on line 300, but not defined == Missing Reference: '0-9' is mentioned on line 300, but not defined ** Obsolete normative reference: RFC 7525 (ref. 'BCP195') (Obsoleted by RFC 9325) ** Obsolete normative reference: RFC 5226 (Obsoleted by RFC 8126) ** Downref: Normative reference to an Informational RFC: RFC 6234 Summary: 3 errors (**), 0 flaws (~~), 3 warnings (==), 1 comment (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 OAuth Working Group N. Sakimura, Ed. 3 Internet-Draft Nomura Research Institute 4 Intended status: Standards Track J. Bradley 5 Expires: January 9, 2016 Ping Identity 6 N. Agarwal 7 Google 8 July 8, 2015 10 Proof Key for Code Exchange by OAuth Public Clients 11 draft-ietf-oauth-spop-15 13 Abstract 15 OAuth 2.0 public clients utilizing the Authorization Code Grant are 16 susceptible to the authorization code interception attack. This 17 specification describes the attack as well as a technique to mitigate 18 against the threat through the use of Proof Key for Code Exchange 19 (PKCE, pronounced "pixy"). 21 Status of This Memo 23 This Internet-Draft is submitted in full conformance with the 24 provisions of BCP 78 and BCP 79. 26 Internet-Drafts are working documents of the Internet Engineering 27 Task Force (IETF). Note that other groups may also distribute 28 working documents as Internet-Drafts. The list of current Internet- 29 Drafts is at http://datatracker.ietf.org/drafts/current/. 31 Internet-Drafts are draft documents valid for a maximum of six months 32 and may be updated, replaced, or obsoleted by other documents at any 33 time. It is inappropriate to use Internet-Drafts as reference 34 material or to cite them other than as "work in progress." 36 This Internet-Draft will expire on January 9, 2016. 38 Copyright Notice 40 Copyright (c) 2015 IETF Trust and the persons identified as the 41 document authors. All rights reserved. 43 This document is subject to BCP 78 and the IETF Trust's Legal 44 Provisions Relating to IETF Documents 45 (http://trustee.ietf.org/license-info) in effect on the date of 46 publication of this document. Please review these documents 47 carefully, as they describe your rights and restrictions with respect 48 to this document. Code Components extracted from this document must 49 include Simplified BSD License text as described in Section 4.e of 50 the Trust Legal Provisions and are provided without warranty as 51 described in the Simplified BSD License. 53 Table of Contents 55 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 56 1.1. Protocol Flow . . . . . . . . . . . . . . . . . . . . . . 5 57 2. Notational Conventions . . . . . . . . . . . . . . . . . . . 6 58 3. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 7 59 3.1. Abbreviations . . . . . . . . . . . . . . . . . . . . . . 7 60 4. Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . 7 61 4.1. Client creates a code verifier . . . . . . . . . . . . . 7 62 4.2. Client creates the code challenge . . . . . . . . . . . . 8 63 4.3. Client sends the code challenge with the authorization 64 request . . . . . . . . . . . . . . . . . . . . . . . . . 8 65 4.4. Server returns the code . . . . . . . . . . . . . . . . . 9 66 4.4.1. Error Response . . . . . . . . . . . . . . . . . . . 9 67 4.5. Client sends the Authorization Code and the Code Verifier 68 to the token endpoint . . . . . . . . . . . . . . . . . . 9 69 4.6. Server verifies code_verifier before returning the tokens 10 70 5. Compatibility . . . . . . . . . . . . . . . . . . . . . . . . 10 71 6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 10 72 6.1. OAuth Parameters Registry . . . . . . . . . . . . . . . . 10 73 6.2. PKCE Code Challenge Method Registry . . . . . . . . . . . 11 74 6.2.1. Registration Template . . . . . . . . . . . . . . . . 11 75 6.2.2. Initial Registry Contents . . . . . . . . . . . . . . 12 76 7. Security Considerations . . . . . . . . . . . . . . . . . . . 12 77 7.1. Entropy of the code_verifier . . . . . . . . . . . . . . 12 78 7.2. Protection against eavesdroppers . . . . . . . . . . . . 13 79 7.3. Salting the code_challenge . . . . . . . . . . . . . . . 13 80 7.4. OAuth security considerations . . . . . . . . . . . . . . 14 81 7.5. TLS security considerations . . . . . . . . . . . . . . . 14 82 8. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 14 83 9. Revision History . . . . . . . . . . . . . . . . . . . . . . 15 84 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 17 85 10.1. Normative References . . . . . . . . . . . . . . . . . . 18 86 10.2. Informative References . . . . . . . . . . . . . . . . . 18 87 Appendix A. Notes on implementing base64url encoding without 88 padding . . . . . . . . . . . . . . . . . . . . . . 18 89 Appendix B. Example for the S256 code_challenge_method . . . . . 19 90 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 20 92 1. Introduction 94 OAuth 2.0 [RFC6749] public clients are susceptible to the 95 authorization code interception attack. 97 The attacker thereby intercepts the authorization code returned from 98 the authorization endpoint within communication path not protected by 99 TLS, such as inter-app communication within the operating system of 100 the client. 102 Once the attacker has gained access to the authorization code it can 103 use it to obtain the access token. 105 Figure 1 shows the attack graphically. In step (1) the native app 106 running on the end device, such as a smart phone, issues an OAuth 2.0 107 Authorization Request via the browser/operating system. The 108 Redirection Endpoint URI in this case typically uses a custom URI 109 scheme. Step (1) happens through a secure API that cannot be 110 intercepted, though it may potentially be observed in advanced attack 111 scenarios. The request then gets forwarded to the OAuth 2.0 112 authorization server in step (2). Because OAuth requires the use of 113 TLS, this communication is protected by TLS, and also cannot be 114 intercepted. The authorization server returns the authorization code 115 in step (3). In step (4), the Authorization Code is returned to the 116 requester via the Redirection Endpoint URI that was provided in step 117 (1). 119 A malicious app that has been designed to attack this native app has 120 previously registered itself as a handler for the custom URI scheme 121 is now able to intercept the Authorization Code in step (4). This 122 allows the attacker to request and obtain an access token in steps 123 (5) and (6), respectively. 125 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ 126 | End Device (e.g., Smart Phone) | 127 | | 128 | +-------------+ +----------+ | (6) Access Token +----------+ 129 | |Legitimate | | Malicious|<--------------------| | 130 | |OAuth 2.0 App| | App |-------------------->| | 131 | +-------------+ +----------+ | (5) Authorization | | 132 | | ^ ^ | Grant | | 133 | | \ | | | | 134 | | \ (4) | | | | 135 | (1) | \ Authz| | | | 136 | Authz| \ Code | | | Authz | 137 | Request| \ | | | Server | 138 | | \ | | | | 139 | | \ | | | | 140 | v \ | | | | 141 | +----------------------------+ | | | 142 | | | | (3) Authz Code | | 143 | | Operating System/ |<--------------------| | 144 | | Browser |-------------------->| | 145 | | | | (2) Authz Request | | 146 | +----------------------------+ | +----------+ 147 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ 149 Figure 1: Authorization Code Interception Attack. 151 A number of pre-conditions need to hold in order for this attack to 152 work: 154 1) The attacker manages to register a malicious application on the 155 client device and registers a custom URI scheme that is also used 156 by another application. 157 The operating systems must allow a custom URI schemes to be 158 registered by multiple applications. 159 2) The OAuth 2.0 authorization code grant is used. 160 3) The attacker has access to the OAuth 2.0 [RFC6749] client_id and 161 client_secret(if provisioned). All OAuth 2.0 native app client- 162 instances use the same client_id. Secrets provisioned in client 163 binary applications cannot be considered confidential. 164 4a) The attacker (via the installed app) is able to observe only the 165 responses from the authorization endpoint. The plain 166 code_challenge_method mitigates only this attack. 167 4b) A more sophisticated attack scenario allows the attacker to 168 observe requests (in addition to responses) to the authorization 169 endpoint. The attacker is, however, not able to act as a man-in- 170 the-middle. This has been caused by leaking http log information 171 in the OS. To mitigate this the S256 code_challenge_method or 172 cryptographically secure code_challenge_method extension must be 173 used. 175 While this is a long list of pre-conditions the described attack has 176 been observed in the wild and has to be considered in OAuth 2.0 177 deployments. 178 While the OAuth 2.0 Threat Model Section 4.4.1 [RFC6819] describes 179 mitigation techniques they are, unfortunately, not applicable since 180 they rely on a per-client instance secret or aper client instance 181 redirect URI. 183 To mitigate this attack, this extension utilizes a dynamically 184 created cryptographically random key called "code verifier". A 185 unique code verifier is created for every authorization request and 186 its transformed value, called "code challenge", is sent to the 187 authorization server to obtain the authorization code. The 188 authorization code obtained is then sent to the token endpoint with 189 the "code verifier" and the server compares it with the previously 190 received request code so that it can perform the proof of possession 191 of the "code verifier" by the client. This works as the mitigation 192 since the attacker would not know this one-time key, since it is sent 193 over TLS and cannot be intercepted. 195 1.1. Protocol Flow 197 +-------------------+ 198 | Authz Server | 199 +--------+ | +---------------+ | 200 | |--(A)- Authorization Request ---->| | | 201 | | + t(code_verifier), t_m | | Authorization | | 202 | | | | Endpoint | | 203 | |<-(B)---- Authorization Code -----| | | 204 | | | +---------------+ | 205 | Client | | | 206 | | | +---------------+ | 207 | |--(C)-- Access Token Request ---->| | | 208 | | + code_verifier | | Token | | 209 | | | | Endpoint | | 210 | |<-(D)------ Access Token ---------| | | 211 +--------+ | +---------------+ | 212 +-------------------+ 214 Figure 2: Abstract Protocol Flow 216 This specification adds additional parameters to the OAuth 2.0 217 Authorization and Access Token Requests, shown in abstract form in 218 Figure 1. 220 A. The client creates and records a secret named the "code_verifier", 221 and derives a transformed version "t(code_verifier)" (referred to 222 as the "code_challenge") which is sent in the OAuth 2.0 223 Authorization Request, along with the transformation method "t_m". 224 B. The Authorization Endpoint responds as usual, but records 225 "t(code_verifier)" and the transformation method. 226 C. The client then sends the authorization code in the Access Token 227 Request as usual, but includes the "code_verifier" secret 228 generated at (A). 229 D. The authorization server transforms "code_verifier" and compares 230 it to "t(code_verifier)" from (B). Access is denied if they are 231 not equal. 233 An attacker who intercepts the Authorization Grant at (B) is unable 234 to redeem it for an Access Token, as they are not in possession of 235 the "code_verifier" secret. 237 2. Notational Conventions 239 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 240 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 241 "OPTIONAL" in this document are to be interpreted as described in Key 242 words for use in RFCs to Indicate Requirement Levels [RFC2119]. If 243 these words are used without being spelled in uppercase then they are 244 to be interpreted with their normal natural language meanings. 246 This specification uses the Augmented Backus-Naur Form (ABNF) 247 notation of [RFC5234]. 249 STRING denotes a sequence of zero or more ASCII [RFC0020] characters. 251 OCTETS denotes a sequence of zero or more octets. 253 ASCII(STRING) denotes the octets of the ASCII [RFC0020] 254 representation of STRING where STRING is a sequence of zero or more 255 ASCII characters. 257 BASE64URL-ENCODE(OCTETS) denotes the base64url encoding of OCTETS, 258 per Section 3 producing a STRING. 260 BASE64URL-DECODE(STRING) denotes the base64url decoding of STRING, 261 per Section 3, producing a sequence of octets. 263 SHA256(OCTETS) denotes a SHA2 256bit hash [RFC6234] of OCTETS. 265 3. Terminology 267 In addition to the terms defined in OAuth 2.0 [RFC6749], this 268 specification defines the following terms: 270 code verifier 271 A cryptographically random string that is used to correlate the 272 authorization request to the token request. 273 code challenge 274 A challenge derived from the code verifier that is sent in the 275 authorization request, to be verified against later. 276 Base64url Encoding 277 Base64 encoding using the URL- and filename-safe character set 278 defined in Section 5 of [RFC4648], with all trailing '=' 279 characters omitted (as permitted by Section 3.2 of [RFC4648]) and 280 without the inclusion of any line breaks, whitespace, or other 281 additional characters. (See Appendix A for notes on implementing 282 base64url encoding without padding.) 284 3.1. Abbreviations 286 ABNF Augmented Backus-Naur Form 287 Authz Authorization 288 PKCE Proof Key for Code Exchange 289 MITM Man-in-the-middle 290 MTI Mandatory To Implement 292 4. Protocol 294 4.1. Client creates a code verifier 296 The client first creates a code verifier, "code_verifier", for each 297 OAuth 2.0 [RFC6749] Authorization Request, in the following manner: 299 code_verifier = high entropy cryptographic random STRING using the 300 Unreserved Characters [A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~" 301 from Sec 2.3 of [RFC3986], with a minimum length of 43 characters and 302 a maximum length of 128 characters. 304 ABNF for "code_verifier" is as follows. 306 code-verifier = 43*128unreserved 307 unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" 308 ALPHA = %x41-5A / %x61-7A 309 DIGIT = %x30-39 311 NOTE: code verifier SHOULD have enough entropy to make it impractical 312 to guess the value. It is RECOMMENDED that the output of a suitable 313 random number generator be used to create a 32-octet sequence. The 314 Octet sequence is then base64url encoded to produce a 43-octet URL 315 safe string to use as the code verifier. 317 4.2. Client creates the code challenge 319 The client then creates a code challenge derived from the code 320 verifier by using one of the following transformations on the code 321 verifier: 323 plain 324 code_challenge = code_verifier 325 S256 326 code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier))) 328 If the client is capable of using "S256", it MUST use "S256", as 329 "S256" is Mandatory To Implement (MTI) on the server. Clients are 330 permitted to use "plain" only if they cannot support "S256" for some 331 technical reason and know via out of band configuration that the 332 server supports "plain". 334 The plain transformation is for compatibility with existing 335 deployments and for constrained environments that can't use the S256 336 transformation. 338 ABNF for "code_challenge" is as follows. 340 code-challenge = 43*128unreserved 341 unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" 342 ALPHA = %x41-5A / %x61-7A 343 DIGIT = %x30-39 345 4.3. Client sends the code challenge with the authorization request 347 The client sends the code challenge as part of the OAuth 2.0 348 Authorization Request (Section 4.1.1 of [RFC6749].) using the 349 following additional parameters: 351 code_challenge REQUIRED. Code challenge. 353 code_challenge_method OPTIONAL, defaults to "plain" if not present 354 in the request. Code verifier transformation method, "S256" or 355 "plain". 357 4.4. Server returns the code 359 When the server issues the authorization code in the authorization 360 response, it MUST associate the "code_challenge" and 361 "code_challenge_method" values with the authorization code so it can 362 be verified later. 364 Typically, the "code_challenge" and "code_challenge_method" values 365 are stored in encrypted form in the "code" itself, but could 366 alternatively be stored on the server, associated with the code. The 367 server MUST NOT include the "code_challenge" value in client requests 368 in a form that other entities can extract. 370 The exact method that the server uses to associate the 371 "code_challenge" with the issued "code" is out of scope for this 372 specification. 374 4.4.1. Error Response 376 If the server requires Proof Key for Code Exchange (PKCE) by OAuth 377 Public Clients, and the client does not send the "code_challenge" in 378 the request, the authorization endpoint MUST return the authorization 379 error response with "error" value set to "invalid_request". The 380 "error_description" or the response of "error_uri" SHOULD explain the 381 nature of error, e.g., code challenge required. 383 If the server supporting PKCE does not support the requested 384 transform, the authorization endpoint MUST return the authorization 385 error response with "error" value set to "invalid_request". The 386 "error_description" or the response of "error_uri" SHOULD explain the 387 nature of error, e.g., transform algorithm not supported. 389 4.5. Client sends the Authorization Code and the Code Verifier to the 390 token endpoint 392 Upon receipt of the Authorization Code, the client sends the Access 393 Token Request to the token endpoint. In addition to the parameters 394 defined in the OAuth 2.0 Access Token Request (Section 4.1.3 of 395 [RFC6749]), it sends the following parameter: 397 code_verifier REQUIRED. Code verifier 399 The code_challenge_method is bound to the Authorization Code when the 400 Authorization Code is issued. That is the method that the token 401 endpoint MUST use to verify the code_verifier. 403 4.6. Server verifies code_verifier before returning the tokens 405 Upon receipt of the request at the Access Token endpoint, the server 406 verifies it by calculating the code challenge from received 407 "code_verifier" and comparing it with the previously associated 408 "code_challenge", after first transforming it according to the 409 "code_challenge_method" method specified by the client. 411 If the "code_challenge_method" from Section 4.2 was "S256", the 412 received "code_verifier" is hashed by SHA-256, then base64url 413 encoded, and then compared to the "code_challenge". i.e., 415 BASE64URL-ENCODE(SHA256(ASCII("code_verifier" ))) == "code_challenge" 417 If the "code_challenge_method" from Section 4.2 was "plain", they are 418 compared directly. i.e., 420 "code_verifier" == "code_challenge". 422 If the values are equal, the Access Token endpoint MUST continue 423 processing as normal (as defined by OAuth 2.0 [RFC6749]). If the 424 values are not equal, an error response indicating "invalid_grant" as 425 described in section 5.2 of [RFC6749] MUST be returned. 427 5. Compatibility 429 Server implementations of this specification MAY accept OAuth2.0 430 Clients that do not implement this extension. If the "code_verifier" 431 is not received from the client in the Authorization Request, servers 432 supporting backwards compatibility revert to a normal OAuth 2.0 433 [RFC6749] protocol. 435 As the OAuth 2.0 [RFC6749] server responses are unchanged by this 436 specification, client implementations of this specification do not 437 need to know if the server has implemented this specification or not, 438 and SHOULD send the additional parameters as defined in Section 3. to 439 all servers. 441 6. IANA Considerations 443 This specification makes a registration request as follows: 445 6.1. OAuth Parameters Registry 447 This specification registers the following parameters in the IANA 448 OAuth Parameters registry defined in OAuth 2.0 [RFC6749]. 450 o Parameter name: code_verifier 451 o Parameter usage location: token request 452 o Change controller: IESG 453 o Specification document(s): this document 455 o Parameter name: code_challenge 456 o Parameter usage location: authorization request 457 o Change controller: IESG 458 o Specification document(s): this document 460 o Parameter name: code_challenge_method 461 o Parameter usage location: authorization request 462 o Change controller: IESG 463 o Specification document(s): this document 465 6.2. PKCE Code Challenge Method Registry 467 This specification establishes the PKCE Code Challenge Method 468 registry. The new registry should be a sub-registry of OAuth 469 Parameters registry. 471 Additional code_challenge_method types for use with the authorization 472 endpoint are registered using the Specification Required policy 473 [RFC5226], which includes review of the request by one or more 474 Designated Experts. The DEs will ensure there is at least a two-week 475 review of the request on the oauth-ext-review@ietf.org mailing list, 476 and that any discussion on that list converges before they respond to 477 the request. To allow for the allocation of values prior to 478 publication, the Designated Expert(s) may approve registration once 479 they are satisfied that an acceptable specification will be 480 published. 482 Registration requests and discussion on the oauth-ext-review@ietf.org 483 mailing list should use an appropriate subject, such as "Request for 484 PKCE code_challenge_method: example"). 486 The Designated Expert(s) should consider the discussion on the 487 mailing list, as well as the overall security properties of the 488 challenge Method when evaluating registration requests. New methods 489 should not disclose the value of the code_verifier in the request to 490 the Authorization endpoint. Denials should include an explanation 491 and, if applicable, suggestions as to how to make the request 492 successful. 494 6.2.1. Registration Template 496 Code Challenge Method Parameter Name: 497 The name requested (e.g., "example"). Because a core goal of this 498 specification is for the resulting representations to be compact, 499 it is RECOMMENDED that the name be short -- not to exceed 8 500 characters without a compelling reason to do so. This name is 501 case-sensitive. Names may not match other registered names in a 502 case-insensitive manner unless the Designated Expert(s) state that 503 there is a compelling reason to allow an exception in this 504 particular case. 505 Change Controller: 506 For Standards Track RFCs, state "IESG". For others, give the name 507 of the responsible party. Other details (e.g., postal address, 508 email address, home page URI) may also be included. 509 Specification Document(s): 510 Reference to the document(s) that specify the parameter, 511 preferably including URI(s) that can be used to retrieve copies of 512 the document(s). An indication of the relevant sections may also 513 be included but is not required. 515 6.2.2. Initial Registry Contents 517 This specification registers the Code Challenge Method Parameter 518 names defined in Section 4.2 in this registry. 520 o Code Challenge Method Parameter Name: "plain" 521 o Change Controller: IESG 522 o Specification Document(s): Section 4.2 of [[ this document ]] 524 o Code Challenge Method Parameter Name: "S256" 525 o Change Controller: IESG 526 o Specification Document(s): Section 4.2 of [[ this document ]] 528 7. Security Considerations 530 7.1. Entropy of the code_verifier 532 The security model relies on the fact that the code verifier is not 533 learned or guessed by the attacker. It is vitally important to 534 adhere to this principle. As such, the code verifier has to be 535 created in such a manner that it is cryptographically random and has 536 high entropy that it is not practical for the attacker to guess. 538 The client SHOULD create a code_verifier with a minimum of 256bits of 539 entropy. This can be done by having a suitable random number 540 generator create a 32-octet sequence. The Octet sequence can then be 541 base64url encoded to produce a 43-octet URL safe string to use as a 542 code_challenge that has the required entropy. 544 7.2. Protection against eavesdroppers 546 Clients MUST NOT downgrade to "plain" after trying "S256" method. 547 Servers that support PKCE are required to support "S256", and servers 548 that do not support PKCE will simply ignore the unknown 549 "code_verifier" OAuth 2.0 (see Section 3.2 of [RFC6749]. Because of 550 that, an error when "S256" is presented can only mean that the server 551 is faulty or that a MITM attacker is trying a downgrade attack. 553 "S256" method protects against eavesdroppers observing or 554 intercepting the "code_challenge", because the challenge cannot be 555 used without the verifier. With the "plain" method, there is a 556 chance that "code_challenge" will be observed by the attacker on the 557 device, or in the http request. Since the code challenge is the same 558 as the code verifier in this case, "plain" method does not protect 559 against the eavesdropping of the initial request. 561 The use of "S256" protects against disclosure of "code_verifier" 562 value to an attacker. 564 Because of this, "plain" SHOULD NOT be used, and exists only for 565 compatibility with deployed implementations where the request path is 566 already protected. The "plain" method SHOULD NOT be used in new 567 implementations, unless they cannot support "S256" for some technical 568 reason. 570 The "S256" code_challenge_method or other cryptographically secure 571 code_challenge_method extension SHOULD be used. The plain 572 code_challenge_method relies on the operating system and transport 573 security not to disclose the request to an attacker. 575 If the code_challenge_method is plain, and the "code_challenge" is to 576 be returned inside authorization "code" to achieve a stateless 577 server, it MUST be encrypted in such a manner that only the server 578 can decrypt and extract it. 580 7.3. Salting the code_challenge 582 In order to reduce implementation complexity Salting is not used in 583 the production of the code_challenge, as the code_verifier contains 584 sufficient entropy to prevent brute force attacks. Concatenating a 585 publicly known value to a code_verifier (containing 256 bits of 586 entropy) and then hashing it with SHA256 to produce a code_challenge 587 would not increase the number of attempts necessary to brute force a 588 valid value for code_verifier. 590 While the S256 transformation is like hashing a password there are 591 important differences. Passwords tend to be relatively low entropy 592 words that can be hashed offline and the hash looked up in a 593 dictionary. By concatenating a unique though public value to each 594 password prior to hashing, the dictionary space that an attacker 595 needs to search is greatly expanded. 597 Modern graphics processors now allow attackers to calculate hashes in 598 real time faster than they could be looked up from a disk. This 599 eliminates the value of the salt in increasing the complexity of a 600 brute force attack for even low entropy passwords. 602 7.4. OAuth security considerations 604 All the OAuth security analysis presented in [RFC6819] applies so 605 readers SHOULD carefully follow it. 607 7.5. TLS security considerations 609 Curent security considerations can be found in Recommendations for 610 Secure Use of TLS and DTLS [BCP195]. This supersedes the TLS version 611 recommendations in OAuth 2.0 [RFC6749]. 613 8. Acknowledgements 615 The initial draft of this specification was created by the OpenID AB/ 616 Connect Working Group of the OpenID Foundation. 618 This specification is the work of the OAuth Working Group, which 619 includes dozens of active and dedicated participants. In particular, 620 the following individuals contributed ideas, feedback, and wording 621 that shaped and formed the final specification: 623 Anthony Nadalin, Microsoft 624 Axel Nenker, Deutsche Telekom 625 Breno de Medeiros, Google 626 Brian Campbell, Ping Identity 627 Chuck Mortimore, Salesforce 628 Dirk Balfanz, Google 629 Eduardo Gueiros, Jive Communications 630 Hannes Tschonfenig, ARM 631 James Manger, Telstra 632 John Bradley, Ping Identity 633 Justin Richer, MIT Kerberos 634 Josh Mandel, Boston Children's Hospital 635 Lewis Adam, Motorola Solutions 636 Madjid Nakhjiri, Samsung 637 Michael B. Jones, Microsoft 638 Nat Sakimura, Nomura Research Institute 639 Naveen Agarwal, Google 640 Paul Madsen, Ping Identity 641 Phil Hunt, Oracle 642 Prateek Mishra, Oracle 643 Ryo Ito, mixi 644 Scott Tomilson, Ping Identity 645 Sergey Beryozkin 646 Takamichi Saito 647 Torsten Lodderstedt, Deutsche Telekom 648 William Denniss, Google 650 9. Revision History 652 -15 654 o Addressed Barry's IESG comments around IANA Registration 655 o Addressed Barry's IESG comments around Sec 7.2 downgrade attack 656 o fix a typo for William and make a small change to Fig 1.1 657 clarifying t_m 658 o more wording changes to sec 7.2 re Barry 659 o made the two SHOULD NOT use plain recommendations consistent. 660 o slightly cleaned up grammer in Sec 7.2 662 -14 664 o #38. Expanded Section 7.2 to explain why plain should not be 665 used. 666 o #39. Modified Section 4.4.1 to discourage the use of plain. 667 o #40. Modified Intro text to explain the attack better. 668 o #41. Added explanation that the token request is protected in the 669 Last paragraph of the Introduction. 670 o #42. Sec 4.2: Removed redundant double quotes caused by spanx. 671 o #43. Sec 4.4: Replaced code with authorization code. 672 o #44. Sec 4.5: say "code_verifier" rather than "secret" 673 o #45. Sec 4.4.1: Expanded PKCE. 674 o #46. Sec 5: SHOULD in para 1 removed. 675 o Added abbreviations section. 677 -13 679 o Fix the parameter usage locations for the OAuth Parameters 680 Registry per Hannes response. 681 o Clarify for IANA that the new registry is a sub-registry of OAuth 682 Parameters registry 683 o aded text on why the code_challenge_method is not sent to the 684 token endpoint. 686 -12 687 o clarify that the client secret we are talking about in the 688 Introduction is a OAuth 2 client_secret. 689 o Update salting security consideration based on Ben's feedback 691 -11 693 o add spanx for plain in sec 4.4 RE Kathleen's comment 694 o Add security consideration on TLS and reference BCP195 695 o Update to make clearer that plain can only be used for backwards 696 compatibility and constrained environments 698 -10 700 o re #33 specify lower limit to code_verifier in prose 701 o remove base64url decode from draft, all steps now use encode only 702 o Expanded MTI 703 o re #33 change length of 32 octet base64url encoded string back to 704 43 octets 706 -09 708 o clean up some external references so they don't point at internal 709 sections 711 -08 713 o changed BASE64URL to BASE64URL-ENCODE to be more consistent with 714 appendix A Fixed lowercase base64url in appendix B 715 o Added appendix B as an example of S256 processing 716 o Change reference for unreserved characters to RFC3986 from 717 base64URL 719 -07 721 o removed unused discovery reference and UTF8 722 o re #32 added ASCII(STRING) to make clear that it is the byte array 723 that is being hashed 724 o re #2 Remove discovery requirement section. 725 o updated Acknowledgement 726 o re #32 remove unneeded UTF8(STRING) definition, and define STRING 727 for ASCII(STRING) 728 o re #32 remove unneeded utf8 reference from BASE64URL- 729 DECODE(STRING) def 730 o resolves #31 unused definition of concatenation 731 o re #30 Update figure text call out the endpoints 732 o re #30 Update figure to call out the endpoints 733 o small wording change to the introduction 734 -06 736 o fix date 737 o replace spop with pkce for registry and other references 738 o re #29 change name again 739 o re #27 removed US-ASCII reference 740 o re #27 updated ABNF for code_verifier 741 o resolves #24 added security consideration for salting 742 o resolves #29 Changed title 743 o updated reference to RFC4634 to RFC6234 re #27 744 o changed reference for US-ASCII to RFC20 re #27 745 o resolves #28 added Acknowledgements 746 o resolves #27 updated ABNF 747 o resolves #26 updated abstract and added Hannes figure 749 -05 751 o Added IANA registry for code_challenge_method + fixed some broken 752 internal references. 754 -04 756 o Added error response to authorization response. 758 -03 760 o Added an abstract protocol diagram and explanation 762 -02 764 o Copy edits 766 -01 768 o Specified exactly two supported transformations 769 o Moved discovery steps to security considerations. 770 o Incorporated readability comments by Eduardo Gueiros. 771 o Changed MUST in 3.1 to SHOULD. 773 -00 775 o Initial IETF version. 777 10. References 778 10.1. Normative References 780 [BCP195] Sheffer, Y., Holz, R., and P. Saint-Andre, 781 "Recommendations for Secure Use of Transport Layer 782 Security (TLS) and Datagram Transport Layer Security 783 (DTLS)", BCP 195, RFC 7525, May 2015. 785 [RFC0020] Cerf, V., "ASCII format for network interchange", RFC 20, 786 October 1969. 788 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 789 Requirement Levels", BCP 14, RFC 2119, March 1997. 791 [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform 792 Resource Identifier (URI): Generic Syntax", STD 66, RFC 793 3986, January 2005. 795 [RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data 796 Encodings", RFC 4648, October 2006. 798 [RFC5226] Narten, T. and H. Alvestrand, "Guidelines for Writing an 799 IANA Considerations Section in RFCs", BCP 26, RFC 5226, 800 May 2008. 802 [RFC5234] Crocker, D. and P. Overell, "Augmented BNF for Syntax 803 Specifications: ABNF", STD 68, RFC 5234, January 2008. 805 [RFC6234] Eastlake, D. and T. Hansen, "US Secure Hash Algorithms 806 (SHA and SHA-based HMAC and HKDF)", RFC 6234, May 2011. 808 [RFC6749] Hardt, D., "The OAuth 2.0 Authorization Framework", RFC 809 6749, October 2012. 811 10.2. Informative References 813 [RFC6819] Lodderstedt, T., McGloin, M., and P. Hunt, "OAuth 2.0 814 Threat Model and Security Considerations", RFC 6819, 815 January 2013. 817 Appendix A. Notes on implementing base64url encoding without padding 819 This appendix describes how to implement a base64url encoding 820 function without padding based upon standard base64 encoding function 821 that uses padding. 823 To be concrete, example C# code implementing these functions is shown 824 below. Similar code could be used in other languages. 826 static string base64urlencode(byte [] arg) 827 { 828 string s = Convert.ToBase64String(arg); // Regular base64 encoder 829 s = s.Split('=')[0]; // Remove any trailing '='s 830 s = s.Replace('+', '-'); // 62nd char of encoding 831 s = s.Replace('/', '_'); // 63rd char of encoding 832 return s; 833 } 835 An example correspondence between unencoded and encoded values 836 follows. The octet sequence below encodes into the string below, 837 which when decoded, reproduces the octet sequence. 839 3 236 255 224 193 841 A-z_4ME 843 Appendix B. Example for the S256 code_challenge_method 845 The client uses output of a suitable random number generator to 846 create a 32-octet sequence. The octets representing the value in 847 this example (using JSON array notation) are:" 849 [116, 24, 223, 180, 151, 153, 224, 37, 79, 250, 96, 125, 216, 173, 850 187, 186, 22, 212, 37, 77, 105, 214, 191, 240, 91, 88, 5, 88, 83, 851 132, 141, 121] 853 Encoding this octet sequence as a Base64url provides the value of the 854 code_verifier: 856 dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk 858 The code_verifier is then hashed via the SHA256 hash function to 859 produce: 861 [19, 211, 30, 150, 26, 26, 216, 236, 47, 22, 177, 12, 76, 152, 46, 862 8, 118, 168, 120, 173, 109, 241, 68, 86, 110, 225, 137, 74, 203, 863 112, 249, 195] 865 Encoding this octet sequence as a base64url provides the value of the 866 code_challenge: 868 E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM 870 The authorization request includes: 872 code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM 873 &code_challange_method=S256 875 The Authorization server then records the code_challenge and 876 code_challenge_method along with the code that is granted to the 877 client. 879 in the request to the token_endpoint the client includes the code 880 received in the authorization response as well as the additional 881 paramater: 883 code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk 885 The Authorization server retrieves the information for the code 886 grant. Based on the recorded code_challange_method being S256, it 887 then hashes and base64url encodes the value of code_verifier. 888 BASE64URL-ENCODE(SHA256(ASCII("code_verifier" ))) 890 The calculated value is then compared with the value of 891 "code_challenge": 893 BASE64URL-ENCODE(SHA256(ASCII("code_verifier" ))) == code_challenge 895 If the two values are equal then the Authorization server can provide 896 the tokens as long as there are no other errors in the request. If 897 the values are not equal then the request must be rejected, and an 898 error returned. 900 Authors' Addresses 902 Nat Sakimura (editor) 903 Nomura Research Institute 904 1-6-5 Marunouchi, Marunouchi Kitaguchi Bldg. 905 Chiyoda-ku, Tokyo 100-0005 906 Japan 908 Phone: +81-3-5533-2111 909 Email: n-sakimura@nri.co.jp 910 URI: http://nat.sakimura.org/ 911 John Bradley 912 Ping Identity 913 Casilla 177, Sucursal Talagante 914 Talagante, RM 915 Chile 917 Phone: +44 20 8133 3718 918 Email: ve7jtb@ve7jtb.com 919 URI: http://www.thread-safe.com/ 921 Naveen Agarwal 922 Google 923 1600 Amphitheatre Pkwy 924 Mountain View, CA 94043 925 USA 927 Phone: +1 650-253-0000 928 Email: naa@google.com 929 URI: http://google.com/