idnits 2.17.1 draft-ietf-oauth-signed-http-request-02.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 is 1 instance of too long lines in the document, the longest one being 6 characters in excess of 72. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year -- The document date (February 03, 2016) is 3002 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) == Outdated reference: A later version (-08) exists of draft-ietf-oauth-pop-architecture-07 ** 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: 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 J. Richer, Ed. 3 Internet-Draft 4 Intended status: Standards Track J. Bradley 5 Expires: August 6, 2016 Ping Identity 6 H. Tschofenig 7 ARM Limited 8 February 03, 2016 10 A Method for Signing HTTP Requests for OAuth 11 draft-ietf-oauth-signed-http-request-02 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 August 6, 2016. 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 . . . . . . . . . . . . . . . . . . 6 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 . . . . . . . . . . . . . . . . . . . . . 8 68 6.1. The 'pop' OAuth Access Token Type . . . . . . . . . . . . 8 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 . . . . . . . . . . . . 9 75 7.3. Entropy of Keys . . . . . . . . . . . . . . . . . . . . . 10 76 7.4. Denial of Service . . . . . . . . . . . . . . . . . . . . 10 77 7.5. Validating the integrity of HTTP Headers and Query 78 Parameters . . . . . . . . . . . . . . . . . . . . . . . 11 79 8. Privacy Considerations . . . . . . . . . . . . . . . . . . . 11 80 9. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 11 81 10. Normative References . . . . . . . . . . . . . . . . . . . . 11 82 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 12 84 1. Introduction 86 In order to prove possession of an access token and its associated 87 key, an OAuth 2.0 client needs to compute some cryptographic function 88 and present the results to the protected resource as a signature. 89 The protected resource then needs to verify the signature and compare 90 that to the expected keys associated with the access token. This is 91 in addition to the normal token protections provided by a bearer 92 token [RFC6750] and transport layer security (TLS). 94 Furthermore, it is desirable to bind the signature to the HTTP 95 request. Ideally, this should be done without replicating the 96 information already present in the HTTP request more than required. 98 However, many HTTP application frameworks insert extra headers, query 99 parameters, and otherwise manipulate the HTTP request on its way from 100 the web server into the application code itself. It is the goal of 101 this draft to have a signature protection mechanism that is 102 sufficiently robust against such deployment constraints while still 103 providing sufficient security benefits. 105 The key required for this signature calculation is distributed via 106 mechanisms described in companion documents (see 107 [I-D.ietf-oauth-pop-key-distribution] and 108 [I-D.ietf-oauth-pop-architecture]). The JSON Web Signature (JWS) 109 specification [RFC7515] is used for computing a digital signature 110 (which uses asymmetric cryptography) or a keyed message digest (in 111 case of symmetric cryptography). 113 The mechanism described in this document assumes that a client is in 114 possession of an access token and asociated key. That client then 115 creates a JSON object including the access token, signs the JSON 116 object using JWS, and issues an request to a resource server for 117 access to a protected resource using the signed object as its 118 authorization. 120 2. Terminology 122 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 123 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 124 "OPTIONAL" in this document are to be interpreted as described in RFC 125 2119 [RFC2119]. 127 Other terms such as "client", "authorization server", "access token", 128 and "protected resource" are inherited from OAuth 2.0 [RFC6749]. 130 We use the term 'sign' (or 'signature') to denote both a keyed 131 message digest and a digital signature operation. 133 3. Generating a JSON Object from an HTTP Request 135 This specification uses JSON Web Signatures [RFC7515] to protect the 136 access token and, optionally, parts of the request. 138 This section describes how to generate a JSON [RFC7159] object from 139 the HTTP request. Each value below is included as a member of the 140 JSON object at the top level. 142 at REQUIRED. The access token value. This string is assumed to have 143 no particular format or structure and remains opaque to the 144 client. 146 ts RECOMMENDED. The timestamp. This integer provides replay 147 protection of the signed JSON object. Its value MUST be a number 148 containing an integer value representing number of whole integer 149 seconds from midnight, January 1, 1970 GMT. 151 m OPTIONAL. The HTTP Method used to make this request. This MUST 152 be the uppercase HTTP verb as a JSON string. 154 u OPTIONAL. The HTTP URL host component as a JSON string. This MAY 155 include the port separated from the host by a colon in host:port 156 format. 158 p OPTIONAL. The HTTP URL path component of the request as an HTTP 159 string. 161 q OPTIONAL. The hashed HTTP URL query parameter map of the request 162 as a two-part JSON array. The first part of this array is a JSON 163 array listing all query parameters that were used in the 164 calculation of the hash in the order that they were added to the 165 hashed value as described below. The second part of this array is 166 a JSON string containing the Base64URL encoded hash itself, 167 calculated as described below. 169 h OPTIONAL. The hashed HTTP request headers as a two-part JSON 170 array. The first part of this array is a JSON array listing all 171 headers that were used in the calculation of the hash in the order 172 that they were added to the hashed value as described below. The 173 second part of this array is a JSON string containing the 174 Base64URL encoded hash itself, calculated as described below. 176 b OPTIONAL. The base64URL encoded hash of the HTTP Request body, 177 calculated as the SHA256 of the byte array of the body 179 All hashes SHALL be calculated using the SHA256 algorithm. [[ Note to 180 WG: do we want crypto agility here? If so how do we signal this ]] 182 The JSON object is signed using the algorithm appropriate to the 183 associated access token key, usually communicated as part of key 184 distribution [I-D.ietf-oauth-pop-key-distribution]. 186 3.1. Calculating the query parameter list and hash 188 To generate the query parameter list and hash, the client creates two 189 data objects: an ordered list of strings to hold the query parameter 190 names and a string buffer to hold the data to be hashed. 192 The client iterates through all query parameters in whatever order it 193 chooses and for each query parameter it does the following: 195 1. Adds the name of the query parameter to the end of the list. 197 2. Encodes the name and value of the query parameter as "name=value" 198 and appends it to the string buffer separated by the ampersand 199 "&" character. 201 Repeated parameter names are processed separately with no special 202 handling. Parameters MAY be skipped by the client if they are not 203 required (or desired) to be covered by the signature. 205 The client then calculates the hash over the resulting string buffer. 206 The list and the hash result are added to a list as the value of the 207 "p" member. 209 For example, the query parameter set of "b=bar", "a=foo", "c=duck" is 210 concatenated into the string: 212 b=bar&a=foo&c=duck 214 When added to the JSON structure using this process, the results are: 216 "p": [["b", "a", "c"], "u4LgkGUWhP9MsKrEjA4dizIllDXluDku6ZqCeyuR-JY"] 218 3.2. Calculating the header list and hash 220 To generate the header list and hash, the client creates two data 221 objects: an ordered list of strings to hold the header names and a 222 string buffer to hold the data to be hashed. 224 The client iterates through all query parameters in whatever order it 225 chooses and for each query parameter it does the following: 227 1. Lowercases the header name. 229 2. Adds the name of the header to the end of the list. 231 3. Encodes the name and value of the header as "name: value" and 232 appends it to the string buffer separated by a newline "\n" 233 character. 235 Repeated header names are processed separately with no special 236 handling. Headers MAY be skipped by the client if they are not 237 required (or desired) to be covered by the signature. 239 The client then calculates the hash over the resulting string buffer. 240 The list and the hash result are added to a list as the value of the 241 "h" member. 243 For example, the headers "Content-Type: application/json" and "Etag: 244 742-3u8f34-3r2nvv3" are concatenated into the string: 246 content-type: application/json 247 etag: 742-3u8f34-3r2nvv3 249 "h": [["content-type", "etag"], "bZA981YJBrPlIzOvplbu3e7ueREXXr38vSkxIBYOaxI"] 251 4. Sending the signed object 253 In order to send the signed object to the protected resource, the 254 client includes it in one of the following three places. 256 4.1. HTTP Authorization header 258 The client SHOULD send the signed object to the protected resource in 259 the Authorization header. The value of the signed object in JWS 260 compact form is appended to the Authorization header as a PoP value. 261 This is the preferred method. Note that if this method is used, the 262 Authorization header MUST NOT be included in the protected elements 263 of the signed object. 265 GET /resource/foo 266 Authorization: PoP eyJ.... 268 4.2. HTTP Form body 270 If the client is sending the request as a form-encoded HTTP message 271 with parameters in the body, the client MAY send the signed object as 272 part of that form body. The value of the signed object in JWS 273 compact form is sent as the form parameter pop_access_token. Note 274 that if this method is used, the body hash cannot be included in the 275 protected elements of the signed object. 277 POST /resource 278 Content-type: application/www-form-encoded 280 pop_access_token=eyJ.... 282 4.3. HTTP Query parameter 284 If neither the Authorization header nor the form-encoded body 285 parameter are available to the client, the client MAY send the signed 286 object as a query parameter. The value of the signed object in JWS 287 compact form is sent as the query parameter pop_access_token. Note 288 that if this method is used, the pop_access_token parameter MUST NOT 289 be included in the protected elements of the signed object. 291 GET /resource?pop_access_token=eyJ.... 293 5. Validating the request 295 Just like with a bearer token [RFC6750], while the access token value 296 included in the signed object is opaque to the client, it MUST be 297 understood by the protected resource in order to fulfill the request. 298 Also like a bearer token, the protected resource traditionally has 299 several methods at its disposal for understanding the access token. 300 It can look up the token locally (such as in a database), it can 301 parse a structured token (such as JWT [RFC7519]), or it can use a 302 service to look up token information (such as introspection 303 [RFC7662]). However token information is looked up, the protected 304 resource MUST have access to the key associated with the access 305 token, which is required to validate the signature of the incoming 306 request. Validation of the signature is done using normal JWS 307 validation for the signature and key type. 309 Additionally, in order to trust any of the hashed components of the 310 HTTP request, the protected resource MUST re-create and verify a hash 311 for each component as described below. This process is a mirror of 312 the process used to create the hashes in the first place, with a mind 313 toward the fact that order may have changed and that elements may 314 have been added or deleted. The protected resource MUST similarly 315 compare the replicated values included in various JSON fields with 316 the corresponding actual values from the request. Failure to do so 317 will allow an attacker to modify the underlying request while at the 318 same time having the application layer verify the signature 319 correctly. 321 5.1. Validating the query parameter list and hash 323 The client has at its disposal a map that indexes the query parameter 324 names to the values given. The client creates a string buffer for 325 calculating the hash. The client then iterates through the "list" 326 portion of the "p" parameter. For each item in the list (in the 327 order of the list) it does the following: 329 1. Fetch the value of the parameter from the HTTP request query 330 parameter map. If a parameter is found in the list of signed 331 parameters but not in the map, the validation fails. 333 2. Encode the parameter as "name=value" and concatenate it to the 334 end of the string buffer, separated by an ampersand character. 336 The client calculates the hash of the string buffer and base64url 337 encodes it. The protected resource compares that string to the 338 string passed in as the hash. If the two match, the hash validates, 339 and all named parameters and their values are considered covered by 340 the signature. 342 There MAY be additional query parameters that are not listed in the 343 list and are therefore not covered by the signature. The client MUST 344 decide whether or not to accept a request with these uncovered 345 parameters. 347 5.2. Validating the header list and hash 349 The client has at its disposal a map that indexes the header names to 350 the values given. The client creates a string buffer for calculating 351 the hash. The client then iterates through the "list" portion of the 352 "h" parameter. For each item in the list (in the order of the list) 353 it does the following: 355 1. Fetch the value of the header from the HTTP request header map. 356 If a header is found in the list of signed parameters but not in 357 the map, the validation fails. 359 2. Encode the parameter as "name: value" and concatenate it to the 360 end of the string buffer, separated by a newline character. 362 The client calculates the hash of the string buffer and base64url 363 encodes it. The protected resource compares that string to the 364 string passed in as the hash. If the two match, the hash validates, 365 and all named headers and their values are considered covered by the 366 signature. 368 There MAY be additional headers that are not listed in the list and 369 are therefore not covered by the signature. The client MUST decide 370 whether or not to accept a request with these uncovered headers. 372 6. IANA Considerations 374 6.1. The 'pop' OAuth Access Token Type 376 Section 11.1 of [RFC6749] defines the OAuth Access Token Type 377 Registry and this document adds another token type to this registry. 379 Type name: pop 381 Additional Token Endpoint Response Parameters: (none) 383 HTTP Authentication Scheme(s): Proof-of-possession access token for 384 use with OAuth 2.0 386 Change controller: IETF 387 Specification document(s): [[ this document ]] 389 6.2. JSON Web Signature and Encryption Type Values Registration 391 This specification registers the "pop" type value in the IANA JSON 392 Web Signature and Encryption Type Values registry [RFC7515]: 394 o "typ" Header Parameter Value: "pop" 396 o Abbreviation for MIME Type: None 398 o Change Controller: IETF 400 o Specification Document(s): [[ this document ]] 402 7. Security Considerations 404 7.1. Offering Confidentiality Protection for Access to Protected 405 Resources 407 This specification can be used with and without Transport Layer 408 Security (TLS). 410 Without TLS this protocol provides a mechanism for verifying the 411 integrity of requests, it provides no confidentiality protection. 412 Consequently, eavesdroppers will have full access to communication 413 content and any further messages exchanged between the client and the 414 resource server. This could be problematic when data is exchanged 415 that requires care, such as personal data. 417 When TLS is used then confidentiality of the transmission can be 418 ensured between endpoints, including both the request and the 419 response. The use of TLS in combination with the signed HTTP request 420 mechanism is highly recommended to ensure the confidentiality of the 421 data returned from the protected resource. 423 7.2. Plaintext Storage of Credentials 425 The mechanism described in this document works in a similar way to 426 many three-party authentication and key exchange mechanisms. In 427 order to compute the signature over the HTTP request, the client must 428 have access to a key bound to the access token in plaintext form. If 429 an attacker were to gain access to these stored secrets at the client 430 or (in case of symmetric keys) at the resource server they would be 431 able to perform any action on behalf of any client just as if they 432 had stolen a bearer token. 434 It is therefore paramount to the security of the protocol that the 435 private keys associated with the access tokens are protected from 436 unauthorized access. 438 7.3. Entropy of Keys 440 Unless TLS is used between the client and the resource server, 441 eavesdroppers will have full access to requests sent by the client. 442 They will thus be able to mount off-line brute-force attacks to 443 attempt recovery of the session key or private key used to compute 444 the keyed message digest or digital signature, respectively. 446 This specification assumes that the key used herein has been 447 distributed via other mechanisms, such as 448 [I-D.ietf-oauth-pop-key-distribution]. Hence, it is the 449 responsibility of the authorization server and or the client to be 450 careful when generating fresh and unique keys with sufficient entropy 451 to resist such attacks for at least the length of time that the 452 session keys (and the access tokens) are valid. 454 For example, if the key bound to the access token is valid for one 455 day, authorization servers must ensure that it is not possible to 456 mount a brute force attack that recovers that key in less than one 457 day. Of course, servers are urged to err on the side of caution, and 458 use the longest key length possible within reason. 460 7.4. Denial of Service 462 This specification includes a number of features which may make 463 resource exhaustion attacks against resource servers possible. For 464 example, a resource server may need to process the incoming request, 465 verify the access token, perform signature verification, and might 466 (in certain circumstances) have to consult back-end databases or the 467 authorization server before granting access to the protected 468 resource. Many of these actions are shared with bearer tokens, but 469 the additional cryptographic overhead of validating the signed 470 request needs to be taken into consideration with deployment of this 471 specification. 473 An attacker may exploit this to perform a denial of service attack by 474 sending a large number of invalid requests to the server. The 475 computational overhead of verifying the keyed message digest alone is 476 not likely sufficient to mount a denial of service attack. To help 477 combat this, it is RECOMMENDED that the protected resource validate 478 the access token (contained in the "at" member of the signed 479 structure) before performing any cryptographic verification 480 calculations. 482 7.5. Validating the integrity of HTTP Headers and Query Parameters 484 This specification provides flexibility for selectively validating 485 the integrity of header fields and message bodies. Since all 486 components of the HTTP request are only optionally validated by this 487 method, and even some components may be validated only in part (e.g., 488 some headers but not others) it is up to protected resource 489 developers to verify that any vital parameters in a request are 490 actually covered by the signature. 492 The application verifying this signature MUST NOT assume that any 493 particular parameter is appropriately covered by the signature unless 494 it is included in the signed structure and the hash is verified. Any 495 applications that are sensitive of header or query parameter order 496 MUST verify the order of the parameters on their own. The 497 application MUST also compare the values in the JSON container with 498 the actual parameters received with the HTTP request (using a direct 499 comparison or a hash calculation, as appropriate). Failure to make 500 this comparison will render the signature mechanism useless for 501 protecting these elements. 503 The behavior of repeated query parameters or repeated HTTP headers is 504 undefined by this specification. If a header or query parameter is 505 repeated on either the outgoing request from the client or the 506 incoming request to the protected resource, that query parameter or 507 header name MUST NOT be covered by the hash and signature. [[ Note to 508 the WG: is this something we need to cover? ]] 510 This specification records the order in which query parameters and 511 headers are hashed, but it does not guarantee that order is preserved 512 between the client and protected resource. 514 8. Privacy Considerations 516 This specification addresses machine to machine communications and 517 raises no privacy considerations beyond existing OAuth transactions. 519 9. Acknowledgements 521 The authors thank the OAuth Working Group for input into this work. 523 10. Normative References 525 [I-D.ietf-oauth-pop-architecture] 526 Hunt, P., Richer, J., Mills, W., Mishra, P., and H. 527 Tschofenig, "OAuth 2.0 Proof-of-Possession (PoP) Security 528 Architecture", draft-ietf-oauth-pop-architecture-07 (work 529 in progress), December 2015. 531 [I-D.ietf-oauth-pop-key-distribution] 532 Bradley, J., Hunt, P., Jones, M., and H. Tschofenig, 533 "OAuth 2.0 Proof-of-Possession: Authorization Server to 534 Client Key Distribution", draft-ietf-oauth-pop-key- 535 distribution-02 (work in progress), October 2015. 537 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 538 Requirement Levels", BCP 14, RFC 2119, 539 DOI 10.17487/RFC2119, March 1997, 540 . 542 [RFC6749] Hardt, D., Ed., "The OAuth 2.0 Authorization Framework", 543 RFC 6749, DOI 10.17487/RFC6749, October 2012, 544 . 546 [RFC6750] Jones, M. and D. Hardt, "The OAuth 2.0 Authorization 547 Framework: Bearer Token Usage", RFC 6750, 548 DOI 10.17487/RFC6750, October 2012, 549 . 551 [RFC7159] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data 552 Interchange Format", RFC 7159, DOI 10.17487/RFC7159, March 553 2014, . 555 [RFC7515] Jones, M., Bradley, J., and N. Sakimura, "JSON Web 556 Signature (JWS)", RFC 7515, DOI 10.17487/RFC7515, May 557 2015, . 559 [RFC7519] Jones, M., Bradley, J., and N. Sakimura, "JSON Web Token 560 (JWT)", RFC 7519, DOI 10.17487/RFC7519, May 2015, 561 . 563 [RFC7662] Richer, J., Ed., "OAuth 2.0 Token Introspection", 564 RFC 7662, DOI 10.17487/RFC7662, October 2015, 565 . 567 Authors' Addresses 569 Justin Richer (editor) 571 Email: ietf@justin.richer.org 573 John Bradley 574 Ping Identity 576 Email: ve7jtb@ve7jtb.com 577 URI: http://www.thread-safe.com/ 578 Hannes Tschofenig 579 ARM Limited 580 Austria 582 Email: Hannes.Tschofenig@gmx.net 583 URI: http://www.tschofenig.priv.at