idnits 2.17.1 draft-ietf-oauth-signed-http-request-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: ---------------------------------------------------------------------------- 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 (August 08, 2016) is 2811 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) ** Downref: Normative reference to an Informational draft: draft-ietf-oauth-pop-architecture (ref. 'I-D.ietf-oauth-pop-architecture') == Outdated reference: A later version (-07) exists of draft-ietf-oauth-pop-key-distribution-02 ** Obsolete normative reference: RFC 7159 (Obsoleted by RFC 8259) Summary: 2 errors (**), 0 flaws (~~), 2 warnings (==), 1 comment (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 OAuth Working Group J. Richer, Ed. 3 Internet-Draft 4 Intended status: Standards Track J. Bradley 5 Expires: February 9, 2017 Ping Identity 6 H. Tschofenig 7 ARM Limited 8 August 08, 2016 10 A Method for Signing HTTP Requests for OAuth 11 draft-ietf-oauth-signed-http-request-03 13 Abstract 15 This document a method for offering data origin authentication and 16 integrity protection of HTTP requests. To convey the relevant data 17 items in the request a JSON-based encapsulation is used and the JSON 18 Web Signature (JWS) technique is re-used. JWS offers integrity 19 protection using symmetric as well as asymmetric cryptography. 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 February 9, 2017. 38 Copyright Notice 40 Copyright (c) 2016 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 2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 3 57 3. Generating a JSON Object from an HTTP Request . . . . . . . . 3 58 3.1. Calculating the query parameter list and hash . . . . . . 4 59 3.2. Calculating the header list and hash . . . . . . . . . . 5 60 4. Sending the signed object . . . . . . . . . . . . . . . . . . 6 61 4.1. HTTP Authorization header . . . . . . . . . . . . . . . . 6 62 4.2. HTTP Form body . . . . . . . . . . . . . . . . . . . . . 6 63 4.3. HTTP Query parameter . . . . . . . . . . . . . . . . . . 7 64 5. Validating the request . . . . . . . . . . . . . . . . . . . 7 65 5.1. Validating the query parameter list and hash . . . . . . 7 66 5.2. Validating the header list and hash . . . . . . . . . . . 8 67 6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 9 68 6.1. The 'pop' OAuth Access Token Type . . . . . . . . . . . . 9 69 6.2. JSON Web Signature and Encryption Type Values 70 Registration . . . . . . . . . . . . . . . . . . . . . . 9 71 7. Security Considerations . . . . . . . . . . . . . . . . . . . 9 72 7.1. Offering Confidentiality Protection for Access to 73 Protected Resources . . . . . . . . . . . . . . . . 9 74 7.2. Plaintext Storage of Credentials . . . . . . . . . . . . 10 75 7.3. Entropy of Keys . . . . . . . . . . . . . . . . . . . . . 10 76 7.4. Denial of Service . . . . . . . . . . . . . . . . . . . . 10 77 7.5. Validating the integrity of HTTP message . . . . . . . . 11 78 8. Privacy Considerations . . . . . . . . . . . . . . . . . . . 12 79 9. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 12 80 10. Normative References . . . . . . . . . . . . . . . . . . . . 12 81 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 13 83 1. Introduction 85 In order to prove possession of an access token and its associated 86 key, an OAuth 2.0 client needs to compute some cryptographic function 87 and present the results to the protected resource as a signature. 88 The protected resource then needs to verify the signature and compare 89 that to the expected keys associated with the access token. This is 90 in addition to the normal token protections provided by a bearer 91 token [RFC6750] and transport layer security (TLS). 93 Furthermore, it is desirable to bind the signature to the HTTP 94 request. Ideally, this should be done without replicating the 95 information already present in the HTTP request more than required. 96 However, many HTTP application frameworks insert extra headers, query 97 parameters, and otherwise manipulate the HTTP request on its way from 98 the web server into the application code itself. It is the goal of 99 this draft to have a signature protection mechanism that is 100 sufficiently robust against such deployment constraints while still 101 providing sufficient security benefits. 103 The key required for this signature calculation is distributed via 104 mechanisms described in companion documents (see 105 [I-D.ietf-oauth-pop-key-distribution] and 106 [I-D.ietf-oauth-pop-architecture]). The JSON Web Signature (JWS) 107 specification [RFC7515] is used for computing a digital signature 108 (which uses asymmetric cryptography) or a keyed message digest (in 109 case of symmetric cryptography). 111 The mechanism described in this document assumes that a client is in 112 possession of an access token and asociated key. That client then 113 creates a JSON object including the access token, signs the JSON 114 object using JWS, and issues an request to a resource server for 115 access to a protected resource using the signed object as its 116 authorization. The protected resource validates the JWS signature 117 and parses the JSON object to obtain token information. 119 2. Terminology 121 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 122 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 123 "OPTIONAL" in this document are to be interpreted as described in RFC 124 2119 [RFC2119]. 126 Other terms such as "client", "authorization server", "access token", 127 and "protected resource" are inherited from OAuth 2.0 [RFC6749]. 129 We use the term 'sign' (or 'signature') to denote both a keyed 130 message digest and a digital signature operation. 132 3. Generating a JSON Object from an HTTP Request 134 This specification uses JSON Web Signatures [RFC7515] to protect the 135 access token and, optionally, parts of the request. 137 This section describes how to generate a JSON [RFC7159] object from 138 the HTTP request. Each value below is included as a member of the 139 JSON object at the top level. 141 at REQUIRED. The access token value. This string is assumed to have 142 no particular format or structure and remains opaque to the 143 client. 145 ts RECOMMENDED. The timestamp. This integer provides replay 146 protection of the signed JSON object. Its value MUST be a number 147 containing an integer value representing number of whole integer 148 seconds from midnight, January 1, 1970 GMT. 150 m OPTIONAL. The HTTP Method used to make this request. This MUST 151 be the uppercase HTTP verb as a JSON string. 153 u OPTIONAL. The HTTP URL host component as a JSON string. This MAY 154 include the port separated from the host by a colon in host:port 155 format. 157 p OPTIONAL. The HTTP URL path component of the request as an HTTP 158 string. 160 q OPTIONAL. The hashed HTTP URL query parameter map of the request 161 as a two-part JSON array. The first part of this array is a JSON 162 array listing all query parameters that were used in the 163 calculation of the hash in the order that they were added to the 164 hashed value as described below. The second part of this array is 165 a JSON string containing the Base64URL encoded hash itself, 166 calculated as described below. 168 h OPTIONAL. The hashed HTTP request headers as a two-part JSON 169 array. The first part of this array is a JSON array listing all 170 headers that were used in the calculation of the hash in the order 171 that they were added to the hashed value as described below. The 172 second part of this array is a JSON string containing the 173 Base64URL encoded hash itself, calculated as described below. 175 b OPTIONAL. The base64URL encoded hash of the HTTP Request body, 176 calculated as the SHA256 of the byte array of the body 178 All hashes SHALL be calculated using the SHA256 algorithm. [[ Note to 179 WG: do we want crypto agility here? If so how do we signal this ]] 181 The JSON object is signed using the algorithm appropriate to the 182 associated access token key, usually communicated as part of key 183 distribution [I-D.ietf-oauth-pop-key-distribution]. 185 3.1. Calculating the query parameter list and hash 187 To generate the query parameter list and hash, the client creates two 188 data objects: an ordered list of strings to hold the query parameter 189 names and a string buffer to hold the data to be hashed. 191 The client iterates through all query parameters in whatever order it 192 chooses and for each query parameter it does the following: 194 1. Adds the name of the query parameter to the end of the list. 196 2. Percent-encodes the name and value of the parameter as specified 197 in [RFC3986]. Note that if the name and value have already been 198 percent-encoded for transit, they are not re-encoded for this 199 step. 201 3. Encodes the name and value of the query parameter as "name=value" 202 and appends it to the string buffer separated by the ampersand 203 "&" character. 205 Repeated parameter names are processed separately with no special 206 handling. Parameters MAY be skipped by the client if they are not 207 required (or desired) to be covered by the signature. 209 The client then calculates the hash over the resulting string buffer. 210 The list and the hash result are added to a list as the value of the 211 "q" member. 213 For example, the query parameter set of "b=bar", "a=foo", "c=duck" is 214 concatenated into the string: 216 b=bar&a=foo&c=duck 218 When added to the JSON structure using this process, the results are: 220 "q": [["b", "a", "c"], "u4LgkGUWhP9MsKrEjA4dizIllDXluDku6ZqCeyuR-JY"] 222 3.2. Calculating the header list and hash 224 To generate the header list and hash, the client creates two data 225 objects: an ordered list of strings to hold the header names and a 226 string buffer to hold the data to be hashed. 228 The client iterates through all query parameters in whatever order it 229 chooses and for each query parameter it does the following: 231 1. Lowercases the header name. 233 2. Adds the name of the header to the end of the list. 235 3. Encodes the name and value of the header as "name: value" and 236 appends it to the string buffer separated by a newline "\n" 237 character. 239 Repeated header names are processed separately with no special 240 handling. Headers MAY be skipped by the client if they are not 241 required (or desired) to be covered by the signature. 243 The client then calculates the hash over the resulting string buffer. 244 The list and the hash result are added to a list as the value of the 245 "h" member. 247 For example, the headers "Content-Type: application/json" and "Etag: 248 742-3u8f34-3r2nvv3" are concatenated into the string: 250 content-type: application/json 251 etag: 742-3u8f34-3r2nvv3 253 "h": [["content-type", "etag"], 254 "bZA981YJBrPlIzOvplbu3e7ueREXXr38vSkxIBYOaxI"] 256 4. Sending the signed object 258 In order to send the signed object to the protected resource, the 259 client includes it in one of the following three places. 261 4.1. HTTP Authorization header 263 The client SHOULD send the signed object to the protected resource in 264 the Authorization header. The value of the signed object in JWS 265 compact form is appended to the Authorization header as a PoP value. 266 This is the preferred method. Note that if this method is used, the 267 Authorization header MUST NOT be included in the protected elements 268 of the signed object. 270 GET /resource/foo 271 Authorization: PoP eyJ....omitted for brevity... 273 4.2. HTTP Form body 275 If the client is sending the request as a form-encoded HTTP message 276 with parameters in the body, the client MAY send the signed object as 277 part of that form body. The value of the signed object in JWS 278 compact form is sent as the form parameter pop_access_token. Note 279 that if this method is used, the body hash cannot be included in the 280 protected elements of the signed object. 282 POST /resource 283 Content-type: application/www-form-encoded 285 pop_access_token=eyJ....omitted for brevity... 287 4.3. HTTP Query parameter 289 If neither the Authorization header nor the form-encoded body 290 parameter are available to the client, the client MAY send the signed 291 object as a query parameter. The value of the signed object in JWS 292 compact form is sent as the query parameter pop_access_token. Note 293 that if this method is used, the pop_access_token parameter MUST NOT 294 be included in the protected elements of the signed object. 296 GET /resource?pop_access_token=eyJ.... 298 5. Validating the request 300 Just like with a bearer token [RFC6750], while the access token value 301 included in the signed object is opaque to the client, it MUST be 302 understood by the protected resource in order to fulfill the request. 303 Also like a bearer token, the protected resource traditionally has 304 several methods at its disposal for understanding the access token. 305 It can look up the token locally (such as in a database), it can 306 parse a structured token (such as JWT [RFC7519]), or it can use a 307 service to look up token information (such as introspection 308 [RFC7662]). Whatever method is used to look up token information, 309 the protected resource MUST have access to the key associated with 310 the access token, as this key is required to validate the signature 311 of the incoming request. Validation of the signature is done using 312 normal JWS validation for the signature and key type. 314 Additionally, in order to trust any of the hashed components of the 315 HTTP request, the protected resource MUST re-create and verify a hash 316 for each component as described below. This process is a mirror of 317 the process used to create the hashes in the first place, with a mind 318 toward the fact that order may have changed and that elements may 319 have been added or deleted. The protected resource MUST similarly 320 compare the replicated values included in various JSON fields with 321 the corresponding actual values from the request. Failure to do so 322 will allow an attacker to modify the underlying request while at the 323 same time having the application layer verify the signature 324 correctly. 326 5.1. Validating the query parameter list and hash 328 The client has at its disposal a map that indexes the query parameter 329 names to the values given. The client creates a string buffer for 330 calculating the hash. The client then iterates through the "list" 331 portion of the "p" parameter. For each item in the list (in the 332 order of the list) it does the following: 334 1. Fetch the value of the parameter from the HTTP request query 335 parameter map. If a parameter is found in the list of signed 336 parameters but not in the map, the validation fails. 338 2. Percent-encodes the name and value of the parameter as specified 339 in [RFC3986]. Note that if the name and value have already been 340 percent-encoded for transit, they are not re-encoded for this 341 step. 343 3. Encode the parameter as "name=value" and concatenate it to the 344 end of the string buffer, separated by an ampersand character. 346 The client calculates the hash of the string buffer and base64url 347 encodes it. The protected resource compares that string to the 348 string passed in as the hash. If the two match, the hash validates, 349 and all named parameters and their values are considered covered by 350 the signature. 352 There MAY be additional query parameters that are not listed in the 353 list and are therefore not covered by the signature. The client MUST 354 decide whether or not to accept a request with these uncovered 355 parameters. 357 5.2. Validating the header list and hash 359 The client has at its disposal a map that indexes the header names to 360 the values given. The client creates a string buffer for calculating 361 the hash. The client then iterates through the "list" portion of the 362 "h" parameter. For each item in the list (in the order of the list) 363 it does the following: 365 1. Fetch the value of the header from the HTTP request header map. 366 If a header is found in the list of signed parameters but not in 367 the map, the validation fails. 369 2. Encode the parameter as "name: value" and concatenate it to the 370 end of the string buffer, separated by a newline character. 372 The client calculates the hash of the string buffer and base64url 373 encodes it. The protected resource compares that string to the 374 string passed in as the hash. If the two match, the hash validates, 375 and all named headers and their values are considered covered by the 376 signature. 378 There MAY be additional headers that are not listed in the list and 379 are therefore not covered by the signature. The client MUST decide 380 whether or not to accept a request with these uncovered headers. 382 6. IANA Considerations 384 6.1. The 'pop' OAuth Access Token Type 386 Section 11.1 of [RFC6749] defines the OAuth Access Token Type 387 Registry and this document adds another token type to this registry. 389 Type name: pop 391 Additional Token Endpoint Response Parameters: (none) 393 HTTP Authentication Scheme(s): Proof-of-possession access token for 394 use with OAuth 2.0 396 Change controller: IETF 398 Specification document(s): [[ this document ]] 400 6.2. JSON Web Signature and Encryption Type Values Registration 402 This specification registers the "pop" type value in the IANA JSON 403 Web Signature and Encryption Type Values registry [RFC7515]: 405 o "typ" Header Parameter Value: "pop" 407 o Abbreviation for MIME Type: None 409 o Change Controller: IETF 411 o Specification Document(s): [[ this document ]] 413 7. Security Considerations 415 7.1. Offering Confidentiality Protection for Access to Protected 416 Resources 418 This specification can be used with and without Transport Layer 419 Security (TLS). 421 Without TLS this protocol provides a mechanism for verifying the 422 integrity of requests, it provides no confidentiality protection. 423 Consequently, eavesdroppers will have full access to communication 424 content and any further messages exchanged between the client and the 425 resource server. This could be problematic when data is exchanged 426 that requires care, such as personal data. 428 When TLS is used then confidentiality of the transmission can be 429 ensured between endpoints, including both the request and the 430 response. The use of TLS in combination with the signed HTTP request 431 mechanism is highly recommended to ensure the confidentiality of the 432 data returned from the protected resource. 434 7.2. Plaintext Storage of Credentials 436 The mechanism described in this document works in a similar way to 437 many three-party authentication and key exchange mechanisms. In 438 order to compute the signature over the HTTP request, the client must 439 have access to a key bound to the access token in plaintext form. If 440 an attacker were to gain access to these stored secrets at the client 441 or (in case of symmetric keys) at the resource server they would be 442 able to perform any action on behalf of any client just as if they 443 had stolen a bearer token. 445 It is therefore paramount to the security of the protocol that the 446 private keys associated with the access tokens are protected from 447 unauthorized access. 449 7.3. Entropy of Keys 451 Unless TLS is used between the client and the resource server, 452 eavesdroppers will have full access to requests sent by the client. 453 They will thus be able to mount off-line brute-force attacks to 454 attempt recovery of the session key or private key used to compute 455 the keyed message digest or digital signature, respectively. 457 This specification assumes that the key used herein has been 458 distributed via other mechanisms, such as 459 [I-D.ietf-oauth-pop-key-distribution]. Hence, it is the 460 responsibility of the authorization server and or the client to be 461 careful when generating fresh and unique keys with sufficient entropy 462 to resist such attacks for at least the length of time that the 463 session keys (and the access tokens) are valid. 465 For example, if the key bound to the access token is valid for one 466 day, authorization servers must ensure that it is not possible to 467 mount a brute force attack that recovers that key in less than one 468 day. Of course, servers are urged to err on the side of caution, and 469 use the longest key length possible within reason. 471 7.4. Denial of Service 473 This specification includes a number of features which may make 474 resource exhaustion attacks against resource servers possible. For 475 example, a resource server may need to process the incoming request, 476 verify the access token, perform signature verification, and might 477 (in certain circumstances) have to consult back-end databases or the 478 authorization server before granting access to the protected 479 resource. Many of these actions are shared with bearer tokens, but 480 the additional cryptographic overhead of validating the signed 481 request needs to be taken into consideration with deployment of this 482 specification. 484 An attacker may exploit this to perform a denial of service attack by 485 sending a large number of invalid requests to the server. The 486 computational overhead of verifying the keyed message digest alone is 487 not likely sufficient to mount a denial of service attack. To help 488 combat this, it is RECOMMENDED that the protected resource validate 489 the access token (contained in the "at" member of the signed 490 structure) before performing any cryptographic verification 491 calculations. 493 7.5. Validating the integrity of HTTP message 495 This specification provides flexibility for selectively validating 496 the integrity of the HTTP request, including header fields, query 497 parameters, and message bodies. Since all components of the HTTP 498 request are only optionally validated by this method, and even some 499 components may be validated only in part (e.g., some headers but not 500 others) it is up to protected resource developers to verify that any 501 vital parameters in a request are actually covered by the signature. 502 Failure to do so could allow an attacker to inject vital parameters 503 or headers into the request, ouside of the protection of the 504 signature. 506 The application verifying this signature MUST NOT assume that any 507 particular parameter is appropriately covered by the signature unless 508 it is included in the signed structure and the hash is verified. Any 509 applications that are sensitive of header or query parameter order 510 MUST verify the order of the parameters on their own. The 511 application MUST also compare the values in the JSON container with 512 the actual parameters received with the HTTP request (using a direct 513 comparison or a hash calculation, as appropriate). Failure to make 514 this comparison will render the signature mechanism useless for 515 protecting these elements. 517 The behavior of repeated query parameters or repeated HTTP headers is 518 undefined by this specification. If a header or query parameter is 519 repeated on either the outgoing request from the client or the 520 incoming request to the protected resource, that query parameter or 521 header name MUST NOT be covered by the hash and signature. 523 This specification records the order in which query parameters and 524 headers are hashed, but it does not guarantee that order is preserved 525 between the client and protected resource. If the order of 526 parameters or headers are significant to the underlying application, 527 it MUST confirm their order on its own, apart from the signature and 528 HTTP message validation. 530 8. Privacy Considerations 532 This specification addresses machine to machine communications and 533 raises no privacy considerations beyond existing OAuth transactions. 535 9. Acknowledgements 537 The authors thank the OAuth Working Group for input into this work. 539 10. Normative References 541 [I-D.ietf-oauth-pop-architecture] 542 Hunt, P., Richer, J., Mills, W., Mishra, P., and H. 543 Tschofenig, "OAuth 2.0 Proof-of-Possession (PoP) Security 544 Architecture", draft-ietf-oauth-pop-architecture-08 (work 545 in progress), July 2016. 547 [I-D.ietf-oauth-pop-key-distribution] 548 Bradley, J., Hunt, P., Jones, M., and H. Tschofenig, 549 "OAuth 2.0 Proof-of-Possession: Authorization Server to 550 Client Key Distribution", draft-ietf-oauth-pop-key- 551 distribution-02 (work in progress), October 2015. 553 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 554 Requirement Levels", BCP 14, RFC 2119, 555 DOI 10.17487/RFC2119, March 1997, 556 . 558 [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform 559 Resource Identifier (URI): Generic Syntax", STD 66, 560 RFC 3986, DOI 10.17487/RFC3986, January 2005, 561 . 563 [RFC6749] Hardt, D., Ed., "The OAuth 2.0 Authorization Framework", 564 RFC 6749, DOI 10.17487/RFC6749, October 2012, 565 . 567 [RFC6750] Jones, M. and D. Hardt, "The OAuth 2.0 Authorization 568 Framework: Bearer Token Usage", RFC 6750, 569 DOI 10.17487/RFC6750, October 2012, 570 . 572 [RFC7159] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data 573 Interchange Format", RFC 7159, DOI 10.17487/RFC7159, March 574 2014, . 576 [RFC7515] Jones, M., Bradley, J., and N. Sakimura, "JSON Web 577 Signature (JWS)", RFC 7515, DOI 10.17487/RFC7515, May 578 2015, . 580 [RFC7519] Jones, M., Bradley, J., and N. Sakimura, "JSON Web Token 581 (JWT)", RFC 7519, DOI 10.17487/RFC7519, May 2015, 582 . 584 [RFC7662] Richer, J., Ed., "OAuth 2.0 Token Introspection", 585 RFC 7662, DOI 10.17487/RFC7662, October 2015, 586 . 588 Authors' Addresses 590 Justin Richer (editor) 592 Email: ietf@justin.richer.org 594 John Bradley 595 Ping Identity 597 Email: ve7jtb@ve7jtb.com 598 URI: http://www.thread-safe.com/ 600 Hannes Tschofenig 601 ARM Limited 602 Austria 604 Email: Hannes.Tschofenig@gmx.net 605 URI: http://www.tschofenig.priv.at