idnits 2.17.1 draft-ietf-oauth-spop-03.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: ---------------------------------------------------------------------------- == The page length should not exceed 58 lines per page, but there was 1 longer page, the longest (page 2) being 60 lines 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 (November 12, 2014) is 3424 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 198, but not defined == Missing Reference: '0-9' is mentioned on line 198, 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 14, 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-03 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 14, 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 (http://trustee.ietf.org/ 44 license-info) in effect on the date of publication of this document. 45 Please review these documents carefully, as they describe your rights 46 and restrictions with respect to this document. Code Components 47 extracted from this document must include Simplified BSD License text 48 as described in Section 4.e of the Trust Legal Provisions and are 49 provided without warranty as described in the Simplified BSD License. 51 Table of Contents 53 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 2 54 1.1. Protocol Flow . . . . . . . . . . . . . . . . . . . . . . 2 55 2. Notational Conventions . . . . . . . . . . . . . . . . . . . . 3 56 3. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 4 57 4. Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 58 4.1. Client creates a code verifier . . . . . . . . . . . . . . 4 59 4.2. Client creates the code challenge . . . . . . . . . . . . 5 60 4.3. Client sends the code challenge with the authorization 61 request . . . . . . . . . . . . . . . . . . . . . . . . . 5 62 4.4. Server returns the code . . . . . . . . . . . . . . . . . 5 63 4.5. Client sends the code and the secret to the token endpoint 6 64 4.6. Server verifies code_verifier before returning the tokens 6 65 5. Compatibility . . . . . . . . . . . . . . . . . . . . . . . . 6 66 6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 6 67 6.1. OAuth Parameters Registry . . . . . . . . . . . . . . . . 7 68 7. Security Considerations . . . . . . . . . . . . . . . . . . . 7 69 7.1. Entropy of the code verifier . . . . . . . . . . . . . . . 7 70 7.2. Protection against eavesdroppers . . . . . . . . . . . . . 7 71 7.3. Checking the Server support . . . . . . . . . . . . . . . 7 72 7.4. OAuth security considerations . . . . . . . . . . . . . . 8 73 8. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 8 74 9. Revision History . . . . . . . . . . . . . . . . . . . . . . . 8 75 10. References . . . . . . . . . . . . . . . . . . . . . . . . . . 9 76 10.1. Normative References . . . . . . . . . . . . . . . . . . 9 77 10.2. Informative References . . . . . . . . . . . . . . . . . 9 78 Appendix A. Notes on implementing base64url encoding without paddi 10 79 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . . 11 81 1. Introduction 83 Public clients in OAuth 2.0 [RFC6749] are susceptible to the 84 authorization "code" interception attack. A malicious client 85 intercepts the authorization code returned from the authorization 86 endpoint and uses it to obtain the access token. This is possible on 87 a public client as there is no client secret associated for it to be 88 sent to the token endpoint. This is especially true on Smartphone 89 applications where the authorization code can be returned through 90 custom URL Schemes where the same scheme can be registered by 91 multiple applications. Under this scenario, the mitigation strategy 92 stated in section 4.4.1 of [RFC6819] does not work as they rely on 93 per-client instance secret or per client instance redirect URI. 95 To mitigate this attack, this extension utilizes a dynamically 96 created cryptographically random key called 'code verifier'. The code 97 verifier is created for every authorization request and its 98 transformed value, called 'code challenge', is sent to the 99 authorization server to obtain the authorization code. The 100 authorization "code" obtained is then sent to the token endpoint with 101 the 'code verifier' and the server compares it with the previously 102 received request code so that it can perform the proof of possession 103 of the 'code verifier' by the client. This works as the mitigation 104 since the attacker would not know this one-time key. 106 1.1. Protocol Flow 107 +--------+ +---------------+ 108 | |--(A)-- Authorization Request --->| | 109 | | + t(code_verifier), t | Resource | 110 | | | Owner | 111 | |<-(B)--- Authorization Grant -----| | 112 | | +---------------+ 113 | Client | 114 | | +---------------+ 115 | |--(C)--- Access Token Request --->| | 116 | | + code_verifier | Authorization | 117 | | | Server | 118 | |<-(D)------ Access Token ---------| | 119 +--------+ +---------------+ 121 This specification adds additional parameters to the OAuth 2.0 122 Authorization and Access Token Requests, shown in abstract form in 123 Figure 1. 125 A. The client creates and records a secret named the "code_verifier", 126 and derives a transformed version "t(code_verifier)" (referred to 127 as the "code_challenge") which is sent in the OAuth 2.0 128 Authorization Request, along with the transformation method "t". 130 B. The resource owner responds as usual, but records 131 "t(code_verifier)" and the transformation method. 133 C. The client then sends the code to the Access Token Request as 134 usual, but includes the "code_verifier" secret generated at (A). 136 D. The authorization server transforms "code_verifier" and compares 137 it to "t(code_verifier)" from (B). Access is denied if they are 138 not equal. 140 An attacker who intercepts the Authorization Grant at (B) is unable 141 to redeem it for an Access Token, as they are not in possession of 142 the "code_verifier" secret. 144 2. Notational Conventions 146 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 147 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 148 "OPTIONAL" in this document are to be interpreted as described in Key 149 words for use in RFCs to Indicate Requirement Levels [RFC2119]. If 150 these words are used without being spelled in uppercase then they are 151 to be interpreted with their normal natural language meanings. 153 This specification uses the Augmented Backus-Naur Form (ABNF) 154 notation of [RFC5234]. 156 BASE64URL(OCTETS) denotes the base64url encoding of OCTETS, per 157 Section 3 producing a [US-ASCII] STRING. 159 BASE64URL-DECODE(STRING) denotes the base64url decoding of STRING, 160 per Section 3, producing a UTF-8 sequence of octets. 162 SHA256(STRING) denotes a SHA2 256bit hash [RFC4634] of STRING. 164 UTF8(STRING) denotes the octets of the UTF-8 [RFC3629] representation 165 of STRING. 167 ASCII(STRING) denotes the octets of the ASCII [US-ASCII] 168 representation of STRING. 170 The concatenation of two values A and B is denoted as A || B. 172 3. Terminology 174 In addition to the terms defined in OAuth 2.0 [RFC6749], this 175 specification defines the following terms: 177 code verifier A cryptographically random string that is used to 178 correlate the authorization request to the token request. 180 code challenge A challenge derived from the code verifier that is 181 sent in the authorization request, to be verified against later. 183 Base64url Encoding Base64 encoding using the URL- and filename-safe 184 character set defined in Section 5 of RFC 4648 [RFC4648], with all 185 trailing '=' characters omitted (as permitted by Section 3.2) and 186 without the inclusion of any line breaks, whitespace, or other 187 additional characters. (See Appendix Appendix A for notes on 188 implementing base64url encoding without padding.) 190 4. Protocol 192 4.1. Client creates a code verifier 194 The client first creates a code verifier, "code_verifier", for each 195 OAuth 2.0 [RFC6749] Authorization Request, in the following manner: 197 code_verifier = high entropy cryptographic random [US-ASCII] sequence 198 using the url and filename safe Alphabet [A-Z] / [a-z] / [0-9] / "-" 199 / "_" from Sec 5 of RFC 4648 [RFC4648], with length less than 128 200 characters. 202 ABNF for "code_verifier" is as follows. 204 code_verifier = 42*128unreserved 205 unreserved = [A-Z] / [a-z] / [0-9] / "-" / "_" 207 NOTE: code verifier SHOULD have enough entropy to make it impractical 208 to guess the value. It is RECOMMENDED that the output of a suitable 209 random number generator be used to create a 32-octet sequence. The 210 Octet sequence is then BASE64URL encoded to produce a 42-octet URL 211 safe string to use as the code verifier. 213 4.2. Client creates the code challenge 215 The client then creates a code challenge, "code_challenge", derived 216 from the "code_verifier" by using one of the following 217 transformations on the "code_verifier": 219 plain "code_challenge" = "code_verifier" 221 S256 "code_challenge" = BASE64URL(SHA256("code_verifier")) 223 It is RECOMMENDED to use the S256 transformation when possible. 225 ABNF for "code_challenge" is as follows. 227 code_challenge = 42*128unreserved 228 unreserved = [A-Z] / [a-z] / [0-9] / "-" / "_" 230 4.3. Client sends the code challenge with the authorization request 232 The client sends the code challenge as part of the OAuth 2.0 233 [RFC6749] Authorization Request (Section 4.1.1.) using the following 234 additional parameters: 236 code_challenge REQUIRED. Code challenge. 238 code_challenge_method OPTIONAL, defaults to "plain". Code verifier 239 transformation method, "S256" or "plain". 241 4.4. Server returns the code 243 When the server issues the "code" in the Authorization Response, it 244 MUST associate the "code_challenge" and "code_challenge_method" 245 values with the "code" so it can be verified later. 247 Typically, the "code_challenge" and "code_challenge_method" values 248 are stored in encrypted form in the "code" itself, but could 249 alternatively be stored on the server, associated with the code. The 250 server MUST NOT include the "code_challenge" value in client requests 251 in a form that other entities can extract. 253 The exact method that the server uses to associate the 254 "code_challenge" with the issued "code" is out of scope for this 255 specification. 257 4.5. Client sends the code and the secret to the token endpoint 259 Upon receipt of the "code", the client sends the Access Token Request 260 to the token endpoint. In addition to the parameters defined in 261 OAuth 2.0 [RFC6749] Access Token Request (Section 4.1.3.), it sends 262 the following parameter: 264 code_verifier REQUIRED. Code verifier 266 4.6. Server verifies code_verifier before returning the tokens 268 Upon receipt of the request at the Access Token endpoint, the server 269 verifies it by calculating the code challenge from received 270 "code_verifier" and comparing it with the previously associated 271 "code_challenge", after first transforming it according to the 272 "code_challenge_method" method specified by the client. 274 If the "code_challenge_method" from 3.2 was "S256", the received 275 "code_verifier" is first hashed with SHA-256 then compared to the 276 base64url decoded "code_challenge". i.e., 278 SHA256("code_verifier" ) == BASE64URL-DECODE("code_challenge"). 280 If the "code_challenge_method" from 3.2 was "none", they are compared 281 directly. i.e., 283 "code_challenge" == "code_verifier". 285 If the values are equal, the Access Token endpoint MUST continue 286 processing as normal (as defined by OAuth 2.0 [RFC6749]). If the 287 values are not equal, an error response indicating "invalid_grant" as 288 described in section 5.2 of OAuth 2.0 [RFC6749] MUST be returned. 290 5. Compatibility 292 Server implementations of this specification MAY accept OAuth2.0 293 Clients that do not implement this extension. If the "code_verifier" 294 is not received from the client in the Authorization Request, servers 295 supporting backwards compatibility SHOULD revert to a normal OAuth 296 2.0 [RFC6749] protocol. 298 As the OAuth 2.0 [RFC6749] server responses are unchanged by this 299 specification, client implementations of this specification do not 300 need to know if the server has implemented this specification or not, 301 and SHOULD send the additional parameters as defined in Section 3. to 302 all servers. 304 6. IANA Considerations 306 This specification makes a registration request as follows: 308 6.1. OAuth Parameters Registry 310 This specification registers the following parameters in the IANA 311 OAuth Parameters registry defined in OAuth 2.0 [RFC6749]. 313 o Parameter name: code_verifier 315 o Parameter usage location: Access Token Request 317 o Change controller: IESG 319 o Specification document(s): this document 321 o Parameter name: code_challenge 323 o Parameter usage location: Authorization Request 325 o Change controller: IESG 327 o Specification document(s): this document 329 o Parameter name: code_challenge_method 331 o Parameter usage location: Authorization Request 333 o Change controller: IESG 335 o Specification document(s): this document 337 7. Security Considerations 339 7.1. Entropy of the code verifier 341 The security model relies on the fact that the code verifier is not 342 learned or guessed by the attacker. It is vitally important to 343 adhere to this principle. As such, the code verifier has to be 344 created in such a manner that it is cryptographically random and has 345 high entropy that it is not practical for the attacker to guess. It 346 is RECOMMENDED that the output of a suitable random number generator 347 be used to create a 32-octet sequence. 349 7.2. Protection against eavesdroppers 351 Unless there is a compelling reason, implementations SHOULD use 352 "S256" method to protect against eavesdroppers intercepting the 353 "code_challenge". If the no transformation algorithm, which is the 354 default algorithm, is used, the client SHOULD make sure that the 355 authorization request is adequately protected from an eavesdropper. 356 If "code_challenge" is to be returned inside authorization "code", it 357 has to be encrypted in such a manner that only the server can decrypt 358 and extract it. 360 7.3. Checking the Server support 361 Before starting the authorization process, the client SHOULD check if 362 the server supports this specification. Confirmation of the server 363 support may be obtained out-of-band or through some other mechanisms 364 such as the discovery document in OpenID Connect Discovery 365 [OpenID.Discovery]. The exact mechanism on how the client obtains 366 this information, or the action it takes as a result is out of scope 367 of this specification. 369 7.4. OAuth security considerations 371 All the OAuth security analysis presented in [RFC6819] applies so 372 readers SHOULD carefully follow it. 374 8. Acknowledgements 376 The initial draft of this specification was created by the OpenID AB/ 377 Connect Working Group of the OpenID Foundation, most notably by the 378 following people: 380 o Naveen Agarwal, Google 382 o Dirk Balfanz, Google 384 o Sergey Beryozkin 386 o John Bradley, Ping Identity 388 o Brian Campbell, Ping Identity 390 o William Denniss, Google 392 o Eduardo Gueiros, Jive Communications 394 o Phil Hunt, Oracle 396 o Ryo Ito, mixi 398 o Michael B. Jones, Microsoft 400 o Torsten Lodderstedt, Deutsche Telekom 402 o Breno de Medeiros, Google 404 o Prateek Mishra, Oracle 406 o Anthony Nadalin, Microsoft 408 o Axel Nenker, Deutsche Telekom 410 o Nat Sakimura, Nomura Research Institute 412 9. Revision History 413 -03 415 o Added an abstract protocol diagram and explanation 417 -02 419 o Copy edits 421 -01 423 o Specified exactly two supported transformations 425 o Moved discovery steps to security considerations. 427 o Incorporated readability comments by Eduardo Gueiros. 429 o Changed MUST in 3.1 to SHOULD. 431 -00 433 o Initial IETF version. 435 10. References 437 10.1. Normative References 439 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 440 Requirement Levels", BCP 14, RFC 2119, March 1997. 442 [RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO 443 10646", STD 63, RFC 3629, November 2003. 445 [RFC4634] Eastlake, D. and T. Hansen, "US Secure Hash Algorithms 446 (SHA and HMAC-SHA)", RFC 4634, July 2006. 448 [RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data 449 Encodings", RFC 4648, October 2006. 451 [RFC5234] Crocker, D. and P. Overell, "Augmented BNF for Syntax 452 Specifications: ABNF", STD 68, RFC 5234, January 2008. 454 [RFC6749] Hardt, D., "The OAuth 2.0 Authorization Framework", RFC 455 6749, October 2012. 457 [US-ASCII] 458 American National Standards Institute, "Coded Character 459 Set -- 7-bit American Standard Code for Information 460 Interchange", ANSI X3.4, 1986. 462 10.2. Informative References 464 [OpenID.Discovery] 465 Sakimura, N., Bradley, J., Jones, M.B. and E. Jay, "OpenID 466 Connect Discovery 1.0", February 2014. 468 [RFC6819] Lodderstedt, T., McGloin, M. and P. Hunt, "OAuth 2.0 469 Threat Model and Security Considerations", RFC 6819, 470 January 2013. 472 Appendix A. Notes on implementing base64url encoding without padding 474 This appendix describes how to implement base64url encoding and 475 decoding functions without padding based upon standard base64 476 encoding and decoding functions that do use padding. 478 To be concrete, example C# code implementing these functions is shown 479 below. Similar code could be used in other languages. 481 static string base64urlencode(byte [] arg) 482 { 483 string s = Convert.ToBase64String(arg); // Regular base64 encoder 484 s = s.Split('=')[0]; // Remove any trailing '='s 485 s = s.Replace('+', '-'); // 62nd char of encoding 486 s = s.Replace('/', '_'); // 63rd char of encoding 487 return s; 488 } 490 static byte [] base64urldecode(string arg) 491 { 492 string s = arg; 493 s = s.Replace('-', '+'); // 62nd char of encoding 494 s = s.Replace('_', '/'); // 63rd char of encoding 495 switch (s.Length % 4) // Pad with trailing '='s 496 { 497 case 0: break; // No pad chars in this case 498 case 2: s += "=="; break; // Two pad chars 499 case 3: s += "="; break; // One pad char 500 default: throw new System.Exception( 501 "Illegal base64url string!"); 502 } 503 return Convert.FromBase64String(s); // Standard base64 decoder 504 } 506 As per the example code above, the number of '=' padding characters 507 that needs to be added to the end of a base64url encoded string 508 without padding to turn it into one with padding is a deterministic 509 function of the length of the encoded string. Specifically, if the 510 length mod 4 is 0, no padding is added; if the length mod 4 is 2, two 511 '=' padding characters are added; if the length mod 4 is 3, one '=' 512 padding character is added; if the length mod 4 is 1, the input is 513 malformed. 515 An example correspondence between unencoded and encoded values 516 follows. The octet sequence below encodes into the string below, 517 which when decoded, reproduces the octet sequence. 519 3 236 255 224 193 521 A-z_4ME 523 Authors' Addresses 525 Nat Sakimura, editor 526 Nomura Research Institute 527 1-6-5 Marunouchi, Marunouchi Kitaguchi Bldg. 528 Chiyoda-ku, Tokyo 100-0005 529 Japan 531 Phone: +81-3-5533-2111 532 Email: n-sakimura@nri.co.jp 533 URI: http://nat.sakimura.org/ 535 John Bradley 536 Ping Identity 537 Casilla 177, Sucursal Talagante 538 Talagante, RM 539 Chile 541 Phone: +44 20 8133 3718 542 Email: ve7jtb@ve7jtb.com 543 URI: http://www.thread-safe.com/ 545 Naveen Agarwal 546 Google 547 1600 Amphitheatre Pkwy 548 Mountain View, CA 94043 549 USA 551 Phone: +1 650-253-0000 552 Email: naa@google.com 553 URI: http://google.com/