idnits 2.17.1 draft-ietf-oauth-spop-04.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 : ---------------------------------------------------------------------------- == There are 2 instances of lines with non-RFC6890-compliant IPv4 addresses in the document. If these are example addresses, they should be changed. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year -- The document date (November 12, 2014) is 3452 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 207, but not defined == Missing Reference: '0-9' is mentioned on line 207, but not defined ** Obsolete normative reference: RFC 4634 (Obsoleted by RFC 6234) -- Possible downref: Non-RFC (?) normative reference: ref. 'US-ASCII' Summary: 1 error (**), 0 flaws (~~), 4 warnings (==), 2 comments (--). 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: May 16, 2015 Ping Identity 6 N. Agarwal 7 Google 8 November 12, 2014 10 Symmetric Proof of Possession for the OAuth Authorization Code Grant 11 draft-ietf-oauth-spop-04 13 Abstract 15 The OAuth 2.0 public client utilizing Authorization Code Grant (RFC 16 6749 - 4.1) is susceptible to the code interception attack. This 17 specification describes a mechanism that acts as a control against 18 this threat. 20 Status of This Memo 22 This Internet-Draft is submitted in full conformance with the 23 provisions of BCP 78 and BCP 79. 25 Internet-Drafts are working documents of the Internet Engineering 26 Task Force (IETF). Note that other groups may also distribute 27 working documents as Internet-Drafts. The list of current Internet- 28 Drafts is at http://datatracker.ietf.org/drafts/current/. 30 Internet-Drafts are draft documents valid for a maximum of six months 31 and may be updated, replaced, or obsoleted by other documents at any 32 time. It is inappropriate to use Internet-Drafts as reference 33 material or to cite them other than as "work in progress." 35 This Internet-Draft will expire on May 16, 2015. 37 Copyright Notice 39 Copyright (c) 2014 IETF Trust and the persons identified as the 40 document authors. All rights reserved. 42 This document is subject to BCP 78 and the IETF Trust's Legal 43 Provisions Relating to IETF Documents 44 (http://trustee.ietf.org/license-info) in effect on the date of 45 publication of this document. Please review these documents 46 carefully, as they describe your rights and restrictions with respect 47 to this document. Code Components extracted from this document must 48 include Simplified BSD License text as described in Section 4.e of 49 the Trust Legal Provisions and are provided without warranty as 50 described in the Simplified BSD License. 52 Table of Contents 54 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 55 1.1. Protocol Flow . . . . . . . . . . . . . . . . . . . . . . 3 56 2. Notational Conventions . . . . . . . . . . . . . . . . . . . 4 57 3. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 4 58 4. Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . 5 59 4.1. Client creates a code verifier . . . . . . . . . . . . . 5 60 4.2. Client creates the code challenge . . . . . . . . . . . . 5 61 4.3. Client sends the code challenge with the authorization 62 request . . . . . . . . . . . . . . . . . . . . . . . . . 6 63 4.4. Server returns the code . . . . . . . . . . . . . . . . . 6 64 4.4.1. Error Response . . . . . . . . . . . . . . . . . . . 6 65 4.5. Client sends the code and the secret to the token 66 endpoint . . . . . . . . . . . . . . . . . . . . . . . . 7 67 4.6. Server verifies code_verifier before returning the tokens 7 68 5. Compatibility . . . . . . . . . . . . . . . . . . . . . . . . 7 69 6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 8 70 6.1. OAuth Parameters Registry . . . . . . . . . . . . . . . . 8 71 7. Security Considerations . . . . . . . . . . . . . . . . . . . 8 72 7.1. Entropy of the code verifier . . . . . . . . . . . . . . 8 73 7.2. Protection against eavesdroppers . . . . . . . . . . . . 9 74 7.3. Checking the Server support . . . . . . . . . . . . . . . 9 75 7.4. OAuth security considerations . . . . . . . . . . . . . . 9 76 8. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 9 77 9. Revision History . . . . . . . . . . . . . . . . . . . . . . 10 78 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 11 79 10.1. Normative References . . . . . . . . . . . . . . . . . . 11 80 10.2. Informative References . . . . . . . . . . . . . . . . . 11 81 Appendix A. Notes on implementing base64url encoding without 82 padding . . . . . . . . . . . . . . . . . . . . . . 11 83 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 12 85 1. Introduction 87 Public clients in OAuth 2.0 [RFC6749] are susceptible to the 88 authorization "code" interception attack. A malicious client 89 intercepts the authorization code returned from the authorization 90 endpoint within communication path not protected by TLS, such as 91 inter-app communication, and uses it to obtain the access token. 92 This is possible on a public client as there is no client secret 93 associated for it to be sent to the token endpoint. This is 94 especially true on Smartphone applications where the authorization 95 code can be returned through custom URL Schemes where the same scheme 96 can be registered by multiple applications. Under this scenario, the 97 mitigation strategy stated in section 4.4.1 of [RFC6819] does not 98 work as they rely on per-client instance secret or per client 99 instance redirect URI. 101 To mitigate this attack, this extension utilizes a dynamically 102 created cryptographically random key called 'code verifier'. The 103 code verifier is created for every authorization request and its 104 transformed value, called 'code challenge', is sent to the 105 authorization server to obtain the authorization code. The 106 authorization "code" obtained is then sent to the token endpoint with 107 the 'code verifier' and the server compares it with the previously 108 received request code so that it can perform the proof of possession 109 of the 'code verifier' by the client. This works as the mitigation 110 since the attacker would not know this one-time key. 112 1.1. Protocol Flow 114 +--------+ +---------------+ 115 | |--(A)-- Authorization Request --->| | 116 | | + t(code_verifier), t | Resource | 117 | | | Owner | 118 | |<-(B)--- Authorization Grant -----| | 119 | | +---------------+ 120 | Client | 121 | | +---------------+ 122 | |--(C)--- Access Token Request --->| | 123 | | + code_verifier | Authorization | 124 | | | Server | 125 | |<-(D)------ Access Token ---------| | 126 +--------+ +---------------+ 128 Figure 1: Abstract Protocol Flow 130 This specification adds additional parameters to the OAuth 2.0 131 Authorization and Access Token Requests, shown in abstract form in 132 Figure 1. 134 A. The client creates and records a secret named the "code_verifier", 135 and derives a transformed version "t(code_verifier)" (referred to 136 as the "code_challenge") which is sent in the OAuth 2.0 137 Authorization Request, along with the transformation method "t". 139 B. The resource owner responds as usual, but records 140 "t(code_verifier)" and the transformation method. 142 C. The client then sends the code to the Access Token Request as 143 usual, but includes the "code_verifier" secret generated at (A). 145 D. The authorization server transforms "code_verifier" and compares 146 it to "t(code_verifier)" from (B). Access is denied if they are 147 not equal. 149 An attacker who intercepts the Authorization Grant at (B) is unable 150 to redeem it for an Access Token, as they are not in possession of 151 the "code_verifier" secret. 153 2. Notational Conventions 155 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 156 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 157 "OPTIONAL" in this document are to be interpreted as described in Key 158 words for use in RFCs to Indicate Requirement Levels [RFC2119]. If 159 these words are used without being spelled in uppercase then they are 160 to be interpreted with their normal natural language meanings. 162 This specification uses the Augmented Backus-Naur Form (ABNF) 163 notation of [RFC5234]. 165 BASE64URL(OCTETS) denotes the base64url encoding of OCTETS, per 166 Section 3 producing a [US-ASCII] STRING. 168 BASE64URL-DECODE(STRING) denotes the base64url decoding of STRING, 169 per Section 3, producing a UTF-8 sequence of octets. 171 SHA256(STRING) denotes a SHA2 256bit hash [RFC4634] of STRING. 173 UTF8(STRING) denotes the octets of the UTF-8 [RFC3629] representation 174 of STRING. 176 ASCII(STRING) denotes the octets of the ASCII [US-ASCII] 177 representation of STRING. 179 The concatenation of two values A and B is denoted as A || B. 181 3. Terminology 183 In addition to the terms defined in OAuth 2.0 [RFC6749], this 184 specification defines the following terms: 186 code verifier A cryptographically random string that is used to 187 correlate the authorization request to the token request. 189 code challenge A challenge derived from the code verifier that is 190 sent in the authorization request, to be verified against later. 192 Base64url Encoding Base64 encoding using the URL- and filename-safe 193 character set defined in Section 5 of RFC 4648 [RFC4648], with all 194 trailing '=' characters omitted (as permitted by Section 3.2) and 195 without the inclusion of any line breaks, whitespace, or other 196 additional characters. (See Appendix A for notes on implementing 197 base64url encoding without padding.) 199 4. Protocol 201 4.1. Client creates a code verifier 203 The client first creates a code verifier, "code_verifier", for each 204 OAuth 2.0 [RFC6749] Authorization Request, in the following manner: 206 code_verifier = high entropy cryptographic random [US-ASCII] sequence 207 using the url and filename safe Alphabet [A-Z] / [a-z] / [0-9] / "-" 208 / "_" from Sec 5 of RFC 4648 [RFC4648], with length less than 128 209 characters. 211 ABNF for "code_verifier" is as follows. 213 code_verifier = 42*128unreserved 214 unreserved = [A-Z] / [a-z] / [0-9] / "-" / "_" 216 NOTE: code verifier SHOULD have enough entropy to make it impractical 217 to guess the value. It is RECOMMENDED that the output of a suitable 218 random number generator be used to create a 32-octet sequence. The 219 Octet sequence is then BASE64URL encoded to produce a 42-octet URL 220 safe string to use as the code verifier. 222 4.2. Client creates the code challenge 224 The client then creates a code challenge, "code_challenge", derived 225 from the "code_verifier" by using one of the following 226 transformations on the "code_verifier": 228 plain "code_challenge" = "code_verifier" 230 S256 "code_challenge" = BASE64URL(SHA256("code_verifier")) 232 It is RECOMMENDED to use the S256 transformation when possible. 234 ABNF for "code_challenge" is as follows. 236 code_challenge = 42*128unreserved 237 unreserved = [A-Z] / [a-z] / [0-9] / "-" / "_" 239 4.3. Client sends the code challenge with the authorization request 241 The client sends the code challenge as part of the OAuth 2.0 242 [RFC6749] Authorization Request (Section 4.1.1.) using the following 243 additional parameters: 245 code_challenge REQUIRED. Code challenge. 247 code_challenge_method OPTIONAL, defaults to "plain". Code verifier 248 transformation method, "S256" or "plain". 250 4.4. Server returns the code 252 When the server issues the "code" in the Authorization Response, it 253 MUST associate the "code_challenge" and "code_challenge_method" 254 values with the "code" so it can be verified later. 256 Typically, the "code_challenge" and "code_challenge_method" values 257 are stored in encrypted form in the "code" itself, but could 258 alternatively be stored on the server, associated with the code. The 259 server MUST NOT include the "code_challenge" value in client requests 260 in a form that other entities can extract. 262 The exact method that the server uses to associate the 263 "code_challenge" with the issued "code" is out of scope for this 264 specification. 266 4.4.1. Error Response 268 If the server requires SPOP, and the client does not send the 269 "code_challenge" in the request, the authorization endpoint MUST 270 return the authorization error response as described in 4.1.2.1. of 271 OAuth 2.0 [RFC6749] with "error" value set to "invalid_request" and 272 "error_description" or "error_uri" whose content explaining the 273 nature of error. 275 If the server supporting SPOP only supports "S256", and the client 276 requests plain transformation, the authorization endpoint MUST return 277 the authorization error response as described in 4.1.2.1. of OAuth 278 2.0 [RFC6749] with "error" value set to "unsupported_spop_transform". 279 The "error_description" or the response of "error_uri" SHOULD explain 280 the nature of error, e.g., transform algorithm not supported. 282 If the client is capable of using "S256", it MUST use "S256", as 283 "S256" is MTI on the server. Clients MAY use plain only if they 284 cannot support "S256" for some technical reason and knows that the 285 server supports "plain". 287 4.5. Client sends the code and the secret to the token endpoint 289 Upon receipt of the "code", the client sends the Access Token Request 290 to the token endpoint. In addition to the parameters defined in 291 OAuth 2.0 [RFC6749] Access Token Request (Section 4.1.3.), it sends 292 the following parameter: 294 code_verifier REQUIRED. Code verifier 296 4.6. Server verifies code_verifier before returning the tokens 298 Upon receipt of the request at the Access Token endpoint, the server 299 verifies it by calculating the code challenge from received 300 "code_verifier" and comparing it with the previously associated 301 "code_challenge", after first transforming it according to the 302 "code_challenge_method" method specified by the client. 304 If the "code_challenge_method" from 3.2 was "S256", the received 305 "code_verifier" is first hashed with SHA-256 then compared to the 306 base64url decoded "code_challenge". i.e., 308 SHA256("code_verifier" ) == BASE64URL-DECODE("code_challenge"). 310 If the "code_challenge_method" from 3.2 was "none", they are compared 311 directly. i.e., 313 "code_challenge" == "code_verifier". 315 If the values are equal, the Access Token endpoint MUST continue 316 processing as normal (as defined by OAuth 2.0 [RFC6749]). If the 317 values are not equal, an error response indicating "invalid_grant" as 318 described in section 5.2 of OAuth 2.0 [RFC6749] MUST be returned. 320 5. Compatibility 322 Server implementations of this specification MAY accept OAuth2.0 323 Clients that do not implement this extension. If the "code_verifier" 324 is not received from the client in the Authorization Request, servers 325 supporting backwards compatibility SHOULD revert to a normal OAuth 326 2.0 [RFC6749] protocol. 328 As the OAuth 2.0 [RFC6749] server responses are unchanged by this 329 specification, client implementations of this specification do not 330 need to know if the server has implemented this specification or not, 331 and SHOULD send the additional parameters as defined in Section 3. to 332 all servers. 334 6. IANA Considerations 336 This specification makes a registration request as follows: 338 6.1. OAuth Parameters Registry 340 This specification registers the following parameters in the IANA 341 OAuth Parameters registry defined in OAuth 2.0 [RFC6749]. 343 o Parameter name: code_verifier 345 o Parameter usage location: Access Token Request 347 o Change controller: IESG 349 o Specification document(s): this document 351 o Parameter name: code_challenge 353 o Parameter usage location: Authorization Request 355 o Change controller: IESG 357 o Specification document(s): this document 359 o Parameter name: code_challenge_method 361 o Parameter usage location: Authorization Request 363 o Change controller: IESG 365 o Specification document(s): this document 367 7. Security Considerations 369 7.1. Entropy of the code verifier 371 The security model relies on the fact that the code verifier is not 372 learned or guessed by the attacker. It is vitally important to 373 adhere to this principle. As such, the code verifier has to be 374 created in such a manner that it is cryptographically random and has 375 high entropy that it is not practical for the attacker to guess. It 376 is RECOMMENDED that the output of a suitable random number generator 377 be used to create a 32-octet sequence. 379 7.2. Protection against eavesdroppers 381 Clients MUST NOT try down grading the algorithm after trying "S256" 382 method. If the server is SPOP compliant, then "S256" method works. 383 If the server does not support SPOP, it does not generate error. 384 Only the time that the server returns that it does not support "S256" 385 is there is a MITM trying the algorithm downgrade attack. 387 "S256" method protects against eavesdroppers observing or 388 intercepting the "code_challenge". If the "plain" method is used, 389 there is a chance that it will be observed by the attacker on the 390 device. The use of "S256" protects against it. 392 If "code_challenge" is to be returned inside authorization "code" to 393 achieve a stateless server, it has to be encrypted in such a manner 394 that only the server can decrypt and extract it. 396 7.3. Checking the Server support 398 Before starting the authorization process, the client SHOULD check if 399 the server supports this specification. Confirmation of the server 400 support may be obtained out-of-band or through some other mechanisms 401 such as the discovery document in OpenID Connect Discovery 402 [OpenID.Discovery]. The exact mechanism on how the client obtains 403 this information, or the action it takes as a result is out of scope 404 of this specification. 406 7.4. OAuth security considerations 408 All the OAuth security analysis presented in [RFC6819] applies so 409 readers SHOULD carefully follow it. 411 8. Acknowledgements 413 The initial draft of this specification was created by the OpenID AB/ 414 Connect Working Group of the OpenID Foundation, most notably by the 415 following people: 417 o Naveen Agarwal, Google 419 o Dirk Balfanz, Google 421 o Sergey Beryozkin 423 o John Bradley, Ping Identity 425 o Brian Campbell, Ping Identity 426 o William Denniss, Google 428 o Eduardo Gueiros, Jive Communications 430 o Phil Hunt, Oracle 432 o Ryo Ito, mixi 434 o Michael B. Jones, Microsoft 436 o Torsten Lodderstedt, Deutsche Telekom 438 o Breno de Medeiros, Google 440 o Prateek Mishra, Oracle 442 o Anthony Nadalin, Microsoft 444 o Axel Nenker, Deutsche Telekom 446 o Nat Sakimura, Nomura Research Institute 448 9. Revision History 450 -04 452 o Added error response to authorization response. 454 -03 456 o Added an abstract protocol diagram and explanation 458 -02 460 o Copy edits 462 -01 464 o Specified exactly two supported transformations 466 o Moved discovery steps to security considerations. 468 o Incorporated readability comments by Eduardo Gueiros. 470 o Changed MUST in 3.1 to SHOULD. 472 -00 473 o Initial IETF version. 475 10. References 477 10.1. Normative References 479 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 480 Requirement Levels", BCP 14, RFC 2119, March 1997. 482 [RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO 483 10646", STD 63, RFC 3629, November 2003. 485 [RFC4634] Eastlake, D. and T. Hansen, "US Secure Hash Algorithms 486 (SHA and HMAC-SHA)", RFC 4634, July 2006. 488 [RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data 489 Encodings", RFC 4648, October 2006. 491 [RFC5234] Crocker, D. and P. Overell, "Augmented BNF for Syntax 492 Specifications: ABNF", STD 68, RFC 5234, January 2008. 494 [RFC6749] Hardt, D., "The OAuth 2.0 Authorization Framework", RFC 495 6749, October 2012. 497 [US-ASCII] 498 American National Standards Institute, "Coded Character 499 Set -- 7-bit American Standard Code for Information 500 Interchange", ANSI X3.4, 1986. 502 10.2. Informative References 504 [OpenID.Discovery] 505 Sakimura, N., Bradley, J., Jones, M., and E. Jay, "OpenID 506 Connect Discovery 1.0", February 2014. 508 [RFC6819] Lodderstedt, T., McGloin, M., and P. Hunt, "OAuth 2.0 509 Threat Model and Security Considerations", RFC 6819, 510 January 2013. 512 Appendix A. Notes on implementing base64url encoding without padding 514 This appendix describes how to implement base64url encoding and 515 decoding functions without padding based upon standard base64 516 encoding and decoding functions that do use padding. 518 To be concrete, example C# code implementing these functions is shown 519 below. Similar code could be used in other languages. 521 static string base64urlencode(byte [] arg) 522 { 523 string s = Convert.ToBase64String(arg); // Regular base64 encoder 524 s = s.Split('=')[0]; // Remove any trailing '='s 525 s = s.Replace('+', '-'); // 62nd char of encoding 526 s = s.Replace('/', '_'); // 63rd char of encoding 527 return s; 528 } 530 static byte [] base64urldecode(string arg) 531 { 532 string s = arg; 533 s = s.Replace('-', '+'); // 62nd char of encoding 534 s = s.Replace('_', '/'); // 63rd char of encoding 535 switch (s.Length % 4) // Pad with trailing '='s 536 { 537 case 0: break; // No pad chars in this case 538 case 2: s += "=="; break; // Two pad chars 539 case 3: s += "="; break; // One pad char 540 default: throw new System.Exception( 541 "Illegal base64url string!"); 542 } 543 return Convert.FromBase64String(s); // Standard base64 decoder 544 } 546 As per the example code above, the number of '=' padding characters 547 that needs to be added to the end of a base64url encoded string 548 without padding to turn it into one with padding is a deterministic 549 function of the length of the encoded string. Specifically, if the 550 length mod 4 is 0, no padding is added; if the length mod 4 is 2, two 551 '=' padding characters are added; if the length mod 4 is 3, one '=' 552 padding character is added; if the length mod 4 is 1, the input is 553 malformed. 555 An example correspondence between unencoded and encoded values 556 follows. The octet sequence below encodes into the string below, 557 which when decoded, reproduces the octet sequence. 559 3 236 255 224 193 561 A-z_4ME 563 Authors' Addresses 564 Nat Sakimura (editor) 565 Nomura Research Institute 566 1-6-5 Marunouchi, Marunouchi Kitaguchi Bldg. 567 Chiyoda-ku, Tokyo 100-0005 568 Japan 570 Phone: +81-3-5533-2111 571 Email: n-sakimura@nri.co.jp 572 URI: http://nat.sakimura.org/ 574 John Bradley 575 Ping Identity 576 Casilla 177, Sucursal Talagante 577 Talagante, RM 578 Chile 580 Phone: +44 20 8133 3718 581 Email: ve7jtb@ve7jtb.com 582 URI: http://www.thread-safe.com/ 584 Naveen Agarwal 585 Google 586 1600 Amphitheatre Pkwy 587 Mountain View, CA 94043 588 USA 590 Phone: +1 650-253-0000 591 Email: naa@google.com 592 URI: http://google.com/