| < draft-ietf-oauth-signed-http-request-01.txt | draft-ietf-oauth-signed-http-request-02.txt > | |||
|---|---|---|---|---|
| OAuth Working Group J. Richer, Ed. | OAuth Working Group J. Richer, Ed. | |||
| Internet-Draft | Internet-Draft | |||
| Intended status: Experimental J. Bradley | Intended status: Standards Track J. Bradley | |||
| Expires: September 10, 2015 Ping Identity | Expires: August 6, 2016 Ping Identity | |||
| H. Tschofenig | H. Tschofenig | |||
| ARM Limited | ARM Limited | |||
| March 09, 2015 | February 03, 2016 | |||
| A Method for Signing an HTTP Requests for OAuth | A Method for Signing HTTP Requests for OAuth | |||
| draft-ietf-oauth-signed-http-request-01.txt | draft-ietf-oauth-signed-http-request-02 | |||
| Abstract | Abstract | |||
| This document a method for offering data origin authentication and | This document a method for offering data origin authentication and | |||
| integrity protection of HTTP requests. To convey the relevant data | integrity protection of HTTP requests. To convey the relevant data | |||
| items in the request a JSON-based encapsulation is used and the JSON | items in the request a JSON-based encapsulation is used and the JSON | |||
| Web Signature (JWS) technique is re-used. JWS offers integrity | Web Signature (JWS) technique is re-used. JWS offers integrity | |||
| protection using symmetric as well as asymmetric cryptography. | protection using symmetric as well as asymmetric cryptography. | |||
| Status of This Memo | Status of This Memo | |||
| skipping to change at page 1, line 37 ¶ | skipping to change at page 1, line 37 ¶ | |||
| Internet-Drafts are working documents of the Internet Engineering | Internet-Drafts are working documents of the Internet Engineering | |||
| Task Force (IETF). Note that other groups may also distribute | Task Force (IETF). Note that other groups may also distribute | |||
| working documents as Internet-Drafts. The list of current Internet- | working documents as Internet-Drafts. The list of current Internet- | |||
| Drafts is at http://datatracker.ietf.org/drafts/current/. | Drafts is at http://datatracker.ietf.org/drafts/current/. | |||
| Internet-Drafts are draft documents valid for a maximum of six months | Internet-Drafts are draft documents valid for a maximum of six months | |||
| and may be updated, replaced, or obsoleted by other documents at any | and may be updated, replaced, or obsoleted by other documents at any | |||
| time. It is inappropriate to use Internet-Drafts as reference | time. It is inappropriate to use Internet-Drafts as reference | |||
| material or to cite them other than as "work in progress." | material or to cite them other than as "work in progress." | |||
| This Internet-Draft will expire on September 10, 2015. | This Internet-Draft will expire on August 6, 2016. | |||
| Copyright Notice | Copyright Notice | |||
| Copyright (c) 2015 IETF Trust and the persons identified as the | Copyright (c) 2016 IETF Trust and the persons identified as the | |||
| document authors. All rights reserved. | document authors. All rights reserved. | |||
| This document is subject to BCP 78 and the IETF Trust's Legal | This document is subject to BCP 78 and the IETF Trust's Legal | |||
| Provisions Relating to IETF Documents | Provisions Relating to IETF Documents | |||
| (http://trustee.ietf.org/license-info) in effect on the date of | (http://trustee.ietf.org/license-info) in effect on the date of | |||
| publication of this document. Please review these documents | publication of this document. Please review these documents | |||
| carefully, as they describe your rights and restrictions with respect | carefully, as they describe your rights and restrictions with respect | |||
| to this document. Code Components extracted from this document must | to this document. Code Components extracted from this document must | |||
| include Simplified BSD License text as described in Section 4.e of | include Simplified BSD License text as described in Section 4.e of | |||
| the Trust Legal Provisions and are provided without warranty as | the Trust Legal Provisions and are provided without warranty as | |||
| described in the Simplified BSD License. | described in the Simplified BSD License. | |||
| Table of Contents | Table of Contents | |||
| 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 | 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 | |||
| 2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 3 | 2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 3 | |||
| 3. Generating a JSON Object from an HTTP Request . . . . . . . . 3 | 3. Generating a JSON Object from an HTTP Request . . . . . . . . 3 | |||
| 3.1. Selection of a hashing algorithm and size . . . . . . . . 4 | 3.1. Calculating the query parameter list and hash . . . . . . 4 | |||
| 3.2. Calculating the query parameter list and hash . . . . . . 4 | 3.2. Calculating the header list and hash . . . . . . . . . . 5 | |||
| 3.3. Calculating the header list and hash . . . . . . . . . . 5 | 4. Sending the signed object . . . . . . . . . . . . . . . . . . 6 | |||
| 4. Verifying the Hashes . . . . . . . . . . . . . . . . . . . . 5 | 4.1. HTTP Authorization header . . . . . . . . . . . . . . . . 6 | |||
| 4.1. Validating the query parameter list and hash . . . . . . 6 | 4.2. HTTP Form body . . . . . . . . . . . . . . . . . . . . . 6 | |||
| 4.2. Validating the header list and hash . . . . . . . . . . . 6 | 4.3. HTTP Query parameter . . . . . . . . . . . . . . . . . . 6 | |||
| 5. Example . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 | 5. Validating the request . . . . . . . . . . . . . . . . . . . 7 | |||
| 6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 7 | 5.1. Validating the query parameter list and hash . . . . . . 7 | |||
| 6.1. The 'pop' OAuth Access Token Type . . . . . . . . . . . . 7 | 5.2. Validating the header list and hash . . . . . . . . . . . 8 | |||
| 6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 8 | ||||
| 6.1. The 'pop' OAuth Access Token Type . . . . . . . . . . . . 8 | ||||
| 6.2. JSON Web Signature and Encryption Type Values | 6.2. JSON Web Signature and Encryption Type Values | |||
| Registration . . . . . . . . . . . . . . . . . . . . . . 8 | Registration . . . . . . . . . . . . . . . . . . . . . . 9 | |||
| 7. Security Considerations . . . . . . . . . . . . . . . . . . . 8 | 7. Security Considerations . . . . . . . . . . . . . . . . . . . 9 | |||
| 7.1. Offering Confidentiality Protection for Access to | 7.1. Offering Confidentiality Protection for Access to | |||
| Protected Resources . . . . . . . . . . . . . . . . 8 | Protected Resources . . . . . . . . . . . . . . . . 9 | |||
| 7.2. Authentication of Resource Servers . . . . . . . . . . . 8 | 7.2. Plaintext Storage of Credentials . . . . . . . . . . . . 9 | |||
| 7.3. Plaintext Storage of Credentials . . . . . . . . . . . . 9 | 7.3. Entropy of Keys . . . . . . . . . . . . . . . . . . . . . 10 | |||
| 7.4. Entropy of Keys . . . . . . . . . . . . . . . . . . . . . 9 | 7.4. Denial of Service . . . . . . . . . . . . . . . . . . . . 10 | |||
| 7.5. Denial of Service . . . . . . . . . . . . . . . . . . . . 9 | 7.5. Validating the integrity of HTTP Headers and Query | |||
| 7.6. Protecting HTTP Header Fields . . . . . . . . . . . . . . 10 | Parameters . . . . . . . . . . . . . . . . . . . . . . . 11 | |||
| 8. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 10 | 8. Privacy Considerations . . . . . . . . . . . . . . . . . . . 11 | |||
| 9. References . . . . . . . . . . . . . . . . . . . . . . . . . 10 | 9. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 11 | |||
| 9.1. Normative References . . . . . . . . . . . . . . . . . . 10 | 10. Normative References . . . . . . . . . . . . . . . . . . . . 11 | |||
| 9.2. Informative References . . . . . . . . . . . . . . . . . 11 | Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 12 | |||
| Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 11 | ||||
| 1. Introduction | 1. Introduction | |||
| In order to protect an HTTP request with a signature, a method for | In order to prove possession of an access token and its associated | |||
| conveying various parameters and to compute a signature is needed. | key, an OAuth 2.0 client needs to compute some cryptographic function | |||
| Ideally, this should be done without replicating the information | and present the results to the protected resource as a signature. | |||
| already present in the HTTP request. This version of the document | The protected resource then needs to verify the signature and compare | |||
| still replicates most of the headers though. | that to the expected keys associated with the access token. This is | |||
| in addition to the normal token protections provided by a bearer | ||||
| The keying material required for this signature calculation is | token [RFC6750] and transport layer security (TLS). | |||
| distributed via mechanisms described in companion documents (see | ||||
| [I-D.bradley-oauth-pop-key-distribution] and | ||||
| [I-D.hunt-oauth-pop-architecture]). The JSON Web Signature (JWS) | ||||
| specification [I-D.ietf-jose-json-web-signature] is re-used for | ||||
| computing a digital signature (which uses asymmetric cryptography) or | ||||
| a keyed message digest (in case of symmetric cryptography). | ||||
| The scope of the mechanism described in this document is shown in | ||||
| Figure 1 where a client in possession of keying material that is tied | ||||
| to the access token creates a JSON object, signs it, and issues an | ||||
| request to a resource server for access to a protected resource. | ||||
| +-----------+ +------------+ | ||||
| | |--(1)- HTTP Request ->| Resource | | ||||
| | Client | (+Signature, +Access Token)->| Server | | ||||
| | | | | | ||||
| | |<-(2)- HTTP Response ---------------| | | ||||
| +-----------+ +------------+ | ||||
| Figure 1: Message Flow. | Furthermore, it is desirable to bind the signature to the HTTP | |||
| request. Ideally, this should be done without replicating the | ||||
| information already present in the HTTP request more than required. | ||||
| Many HTTP application frameworks insert extra headers, query | However, many HTTP application frameworks insert extra headers, query | |||
| parameters, and otherwise manipulate the HTTP request on its way from | parameters, and otherwise manipulate the HTTP request on its way from | |||
| the web server into the application code itself. It is the goal of | the web server into the application code itself. It is the goal of | |||
| this draft to have a signature protection mechanism that is | this draft to have a signature protection mechanism that is | |||
| sufficiently robust against such deployment constraints (while still | sufficiently robust against such deployment constraints while still | |||
| providing sufficient security benefits). | providing sufficient security benefits. | |||
| The method of conveying the token and signed request to the protected | The key required for this signature calculation is distributed via | |||
| resource server is undefined by this document, but [RFC6750] could be | mechanisms described in companion documents (see | |||
| re-used. | [I-D.ietf-oauth-pop-key-distribution] and | |||
| [I-D.ietf-oauth-pop-architecture]). The JSON Web Signature (JWS) | ||||
| specification [RFC7515] is used for computing a digital signature | ||||
| (which uses asymmetric cryptography) or a keyed message digest (in | ||||
| case of symmetric cryptography). | ||||
| The mechanism described in this document does not provide | The mechanism described in this document assumes that a client is in | |||
| authentication of the resource server to the client. This version of | possession of an access token and asociated key. That client then | |||
| the document does not provide a cryptographic binding to Transport | creates a JSON object including the access token, signs the JSON | |||
| Layer Security (TLS) used underneath the an HTTPS request. | object using JWS, and issues an request to a resource server for | |||
| access to a protected resource using the signed object as its | ||||
| authorization. | ||||
| 2. Terminology | 2. Terminology | |||
| The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", | |||
| "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this | "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and | |||
| document are to be interpreted as described in RFC 2119 [RFC2119]. | "OPTIONAL" in this document are to be interpreted as described in RFC | |||
| 2119 [RFC2119]. | ||||
| Other terms such as "client", "authorization server", "access token", | ||||
| and "protected resource" are inherited from OAuth 2.0 [RFC6749]. | ||||
| We use the term 'sign' (or 'signature') to denote both a keyed | We use the term 'sign' (or 'signature') to denote both a keyed | |||
| message digest and a digital signature operation. | message digest and a digital signature operation. | |||
| 3. Generating a JSON Object from an HTTP Request | 3. Generating a JSON Object from an HTTP Request | |||
| This section describes how to generate a JSON object below is | This specification uses JSON Web Signatures [RFC7515] to protect the | |||
| included as a member of the JSON object. All members are OPTIONAL. | access token and, optionally, parts of the request. | |||
| m The HTTP Method used to make this request. This MUST be the | This section describes how to generate a JSON [RFC7159] object from | |||
| uppercase HTTP verb as a JSON string. | the HTTP request. Each value below is included as a member of the | |||
| JSON object at the top level. | ||||
| u The HTTP URL host component as a JSON string. This MAY include | at REQUIRED. The access token value. This string is assumed to have | |||
| the port separated from the host by a colon in host:port format. | no particular format or structure and remains opaque to the | |||
| client. | ||||
| p The HTTP URL path component of the request as an HTTP string. | ts RECOMMENDED. The timestamp. This integer provides replay | |||
| protection of the signed JSON object. Its value MUST be a number | ||||
| containing an integer value representing number of whole integer | ||||
| seconds from midnight, January 1, 1970 GMT. | ||||
| q The hashed HTTP URL query parameter map of the request as a two- | m OPTIONAL. The HTTP Method used to make this request. This MUST | |||
| part JSON array. The first part of this array is a JSON array | be the uppercase HTTP verb as a JSON string. | |||
| listing all query parameters that were used in the calculation of | ||||
| the hash in the order that they were added to the hashed value as | ||||
| described below. The second part of this array is a JSON string | ||||
| containing the Base64URL encoded hash itself, calculated as | ||||
| described below. | ||||
| h The hashed HTTP request headers as a two-part JSON array. The | u OPTIONAL. The HTTP URL host component as a JSON string. This MAY | |||
| first part of this array is a JSON array listing all headers that | include the port separated from the host by a colon in host:port | |||
| were used in the calculation of the hash in the order that they | format. | |||
| were added to the hashed value as described below. The second | ||||
| part of this array is a JSON string containing the Base64URL | ||||
| encoded hash itself, calculated as described below. | ||||
| b The base64URL encoded hash of the HTTP Request body, calculated as | p OPTIONAL. The HTTP URL path component of the request as an HTTP | |||
| the HMAC of the byte array of the body. | string. | |||
| ts The "ts" (timestamp) element provides replay protection of the | q OPTIONAL. The hashed HTTP URL query parameter map of the request | |||
| JSON object. Its value MUST be a number containing an IntDate | as a two-part JSON array. The first part of this array is a JSON | |||
| value representing number of whole integer seconds from midnight, | array listing all query parameters that were used in the | |||
| January 1, 1970 GMT. | calculation of the hash in the order that they were added to the | |||
| hashed value as described below. The second part of this array is | ||||
| a JSON string containing the Base64URL encoded hash itself, | ||||
| calculated as described below. | ||||
| 3.1. Selection of a hashing algorithm and size | h OPTIONAL. The hashed HTTP request headers as a two-part JSON | |||
| array. The first part of this array is a JSON array listing all | ||||
| headers that were used in the calculation of the hash in the order | ||||
| that they were added to the hashed value as described below. The | ||||
| second part of this array is a JSON string containing the | ||||
| Base64URL encoded hash itself, calculated as described below. | ||||
| The hashes SHALL be calculated using the HMAC algorithm using a hash | b OPTIONAL. The base64URL encoded hash of the HTTP Request body, | |||
| size equal to the size of the surrounding JWT's alg header field. | calculated as the SHA256 of the byte array of the body | |||
| That is, if the JWT uses HS256 or RS256, the HMAC here uses a 256-bit | ||||
| HMAC. If the JWT uses RS512, the HMAC here uses 512-bit HMAC, and so | ||||
| forth. | ||||
| 3.2. Calculating the query parameter list and hash | All hashes SHALL be calculated using the SHA256 algorithm. [[ Note to | |||
| WG: do we want crypto agility here? If so how do we signal this ]] | ||||
| The JSON object is signed using the algorithm appropriate to the | ||||
| associated access token key, usually communicated as part of key | ||||
| distribution [I-D.ietf-oauth-pop-key-distribution]. | ||||
| 3.1. Calculating the query parameter list and hash | ||||
| To generate the query parameter list and hash, the client creates two | To generate the query parameter list and hash, the client creates two | |||
| data objects: an ordered list of strings to hold the query parameter | data objects: an ordered list of strings to hold the query parameter | |||
| names and a string buffer to hold the data to be hashed. | names and a string buffer to hold the data to be hashed. | |||
| The client iterates through all query parameters in whatever order it | The client iterates through all query parameters in whatever order it | |||
| chooses and for each query parameter it does the following: | chooses and for each query parameter it does the following: | |||
| 1. Adds the name of the query parameter to the end of the list. | 1. Adds the name of the query parameter to the end of the list. | |||
| 2. Encodes the name and value of the query parameter as "name=value" | 2. Encodes the name and value of the query parameter as "name=value" | |||
| and appends it to the string buffer. [[Separated by an | and appends it to the string buffer separated by the ampersand | |||
| ampersand? Alternatively we could have this also pulled into an | "&" character. | |||
| ordered list and post-process the concatenation, but that might | ||||
| be too deep into the weeds. ]] | ||||
| Repeated parameter names are processed separately with no special | Repeated parameter names are processed separately with no special | |||
| handling. Parameters MAY be skipped by the client if they are not | handling. Parameters MAY be skipped by the client if they are not | |||
| required (or desired) to be covered by the signature. | required (or desired) to be covered by the signature. | |||
| The client then calculates the HMAC hash over the resulting string | The client then calculates the hash over the resulting string buffer. | |||
| buffer. The list and the hash result are added as the value of the | The list and the hash result are added to a list as the value of the | |||
| "p" member. | "p" member. | |||
| 3.3. Calculating the header list and hash | For example, the query parameter set of "b=bar", "a=foo", "c=duck" is | |||
| concatenated into the string: | ||||
| b=bar&a=foo&c=duck | ||||
| When added to the JSON structure using this process, the results are: | ||||
| "p": [["b", "a", "c"], "u4LgkGUWhP9MsKrEjA4dizIllDXluDku6ZqCeyuR-JY"] | ||||
| 3.2. Calculating the header list and hash | ||||
| To generate the header list and hash, the client creates two data | To generate the header list and hash, the client creates two data | |||
| objects: an ordered list of strings to hold the header names and a | objects: an ordered list of strings to hold the header names and a | |||
| string buffer to hold the data to be hashed. | string buffer to hold the data to be hashed. | |||
| The client iterates through all query parameters in whatever order it | The client iterates through all query parameters in whatever order it | |||
| chooses and for each query parameter it does the following: | chooses and for each query parameter it does the following: | |||
| 1. Adds the name of the header to the end of the list. | 1. Lowercases the header name. | |||
| 2. Encodes the name and value of the header as "name: value" and | 2. Adds the name of the header to the end of the list. | |||
| appends it to the string buffer. [[Separated by a newline? | ||||
| Alternatively we could have this also pulled into an ordered list | 3. Encodes the name and value of the header as "name: value" and | |||
| and post-process the concatenation, but that might be too deep | appends it to the string buffer separated by a newline "\n" | |||
| into the weeds. ]] | character. | |||
| Repeated header names are processed separately with no special | Repeated header names are processed separately with no special | |||
| handling. Headers MAY be skipped by the client if they are not | handling. Headers MAY be skipped by the client if they are not | |||
| required (or desired) to be covered by the signature. | required (or desired) to be covered by the signature. | |||
| The client then calculates the HMAC hash over the resulting string | The client then calculates the hash over the resulting string buffer. | |||
| buffer. The list and the hash result are added as the value of the | The list and the hash result are added to a list as the value of the | |||
| "h" member. | "h" member. | |||
| 4. Verifying the Hashes | For example, the headers "Content-Type: application/json" and "Etag: | |||
| 742-3u8f34-3r2nvv3" are concatenated into the string: | ||||
| Validation of the overall signature is done using the standard JWS | content-type: application/json | |||
| mechanisms for JSON structures. However, in order to trust any of | etag: 742-3u8f34-3r2nvv3 | |||
| the hashed mechanisms above, an application MUST re-create and verify | ||||
| a hash for each component. Additionally, an application MUST compare | ||||
| the replicated values included in various JSON fields with the actual | ||||
| header fields of the request. Failure to-do so will allow an | ||||
| attacker to modify the underlying request, connect do different | ||||
| resources while at the same time having the application layer verify | ||||
| the signature correctly. | ||||
| 4.1. Validating the query parameter list and hash | "h": [["content-type", "etag"], "bZA981YJBrPlIzOvplbu3e7ueREXXr38vSkxIBYOaxI"] | |||
| 4. Sending the signed object | ||||
| In order to send the signed object to the protected resource, the | ||||
| client includes it in one of the following three places. | ||||
| 4.1. HTTP Authorization header | ||||
| The client SHOULD send the signed object to the protected resource in | ||||
| the Authorization header. The value of the signed object in JWS | ||||
| compact form is appended to the Authorization header as a PoP value. | ||||
| This is the preferred method. Note that if this method is used, the | ||||
| Authorization header MUST NOT be included in the protected elements | ||||
| of the signed object. | ||||
| GET /resource/foo | ||||
| Authorization: PoP eyJ.... | ||||
| 4.2. HTTP Form body | ||||
| If the client is sending the request as a form-encoded HTTP message | ||||
| with parameters in the body, the client MAY send the signed object as | ||||
| part of that form body. The value of the signed object in JWS | ||||
| compact form is sent as the form parameter pop_access_token. Note | ||||
| that if this method is used, the body hash cannot be included in the | ||||
| protected elements of the signed object. | ||||
| POST /resource | ||||
| Content-type: application/www-form-encoded | ||||
| pop_access_token=eyJ.... | ||||
| 4.3. HTTP Query parameter | ||||
| If neither the Authorization header nor the form-encoded body | ||||
| parameter are available to the client, the client MAY send the signed | ||||
| object as a query parameter. The value of the signed object in JWS | ||||
| compact form is sent as the query parameter pop_access_token. Note | ||||
| that if this method is used, the pop_access_token parameter MUST NOT | ||||
| be included in the protected elements of the signed object. | ||||
| GET /resource?pop_access_token=eyJ.... | ||||
| 5. Validating the request | ||||
| Just like with a bearer token [RFC6750], while the access token value | ||||
| included in the signed object is opaque to the client, it MUST be | ||||
| understood by the protected resource in order to fulfill the request. | ||||
| Also like a bearer token, the protected resource traditionally has | ||||
| several methods at its disposal for understanding the access token. | ||||
| It can look up the token locally (such as in a database), it can | ||||
| parse a structured token (such as JWT [RFC7519]), or it can use a | ||||
| service to look up token information (such as introspection | ||||
| [RFC7662]). However token information is looked up, the protected | ||||
| resource MUST have access to the key associated with the access | ||||
| token, which is required to validate the signature of the incoming | ||||
| request. Validation of the signature is done using normal JWS | ||||
| validation for the signature and key type. | ||||
| Additionally, in order to trust any of the hashed components of the | ||||
| HTTP request, the protected resource MUST re-create and verify a hash | ||||
| for each component as described below. This process is a mirror of | ||||
| the process used to create the hashes in the first place, with a mind | ||||
| toward the fact that order may have changed and that elements may | ||||
| have been added or deleted. The protected resource MUST similarly | ||||
| compare the replicated values included in various JSON fields with | ||||
| the corresponding actual values from the request. Failure to do so | ||||
| will allow an attacker to modify the underlying request while at the | ||||
| same time having the application layer verify the signature | ||||
| correctly. | ||||
| 5.1. Validating the query parameter list and hash | ||||
| The client has at its disposal a map that indexes the query parameter | The client has at its disposal a map that indexes the query parameter | |||
| names to the values given. The client creates a string buffer for | names to the values given. The client creates a string buffer for | |||
| calculating the hash. The client then iterates through the "list" | calculating the hash. The client then iterates through the "list" | |||
| portion of the "p" parameter. For each item in the list (in the | portion of the "p" parameter. For each item in the list (in the | |||
| order of the list) it does the following: | order of the list) it does the following: | |||
| 1. Fetch the value of the parameter from the HTTP request parameter | 1. Fetch the value of the parameter from the HTTP request query | |||
| map. If a parameter is found in the list of signed parameters | parameter map. If a parameter is found in the list of signed | |||
| but not in the map, the validation fails. | parameters but not in the map, the validation fails. | |||
| 2. Encode the parameter as "name=value" and concatenate it to the | 2. Encode the parameter as "name=value" and concatenate it to the | |||
| end of the string buffer. [[same separator issue as above.]] | end of the string buffer, separated by an ampersand character. | |||
| The client calculates the hash of the string buffer and base64url | The client calculates the hash of the string buffer and base64url | |||
| encodes it. The client compares that string to the string passed in | encodes it. The protected resource compares that string to the | |||
| as the hash. If the two match, the hash validates, and all named | string passed in as the hash. If the two match, the hash validates, | |||
| parameters and their values are considered covered by the signature. | and all named parameters and their values are considered covered by | |||
| the signature. | ||||
| There MAY be additional query parameters that are not listed in the | There MAY be additional query parameters that are not listed in the | |||
| list and are therefore not covered by the signature. The client MUST | list and are therefore not covered by the signature. The client MUST | |||
| decide whether or not to accept a request with these uncovered | decide whether or not to accept a request with these uncovered | |||
| parameters. | parameters. | |||
| 4.2. Validating the header list and hash | 5.2. Validating the header list and hash | |||
| The client has at its disposal a map that indexes the header names to | The client has at its disposal a map that indexes the header names to | |||
| the values given. The client creates a string buffer for calculating | the values given. The client creates a string buffer for calculating | |||
| the hash. The client then iterates through the "list" portion of the | the hash. The client then iterates through the "list" portion of the | |||
| "h" parameter. For each item in the list (in the order of the list) | "h" parameter. For each item in the list (in the order of the list) | |||
| it does the following: | it does the following: | |||
| 1. Fetch the value of the header from the HTTP request header map. | 1. Fetch the value of the header from the HTTP request header map. | |||
| If a header is found in the list of signed parameters but not in | If a header is found in the list of signed parameters but not in | |||
| the map, the validation fails. | the map, the validation fails. | |||
| 2. Encode the parameter as "name: value" and concatenate it to the | 2. Encode the parameter as "name: value" and concatenate it to the | |||
| end of the string buffer. [[same separator issue as above.]] | end of the string buffer, separated by a newline character. | |||
| The client calculates the hash of the string buffer and base64url | The client calculates the hash of the string buffer and base64url | |||
| encodes it. The client compares that string to the string passed in | encodes it. The protected resource compares that string to the | |||
| as the hash. If the two match, the hash validates, and all named | string passed in as the hash. If the two match, the hash validates, | |||
| headers and their values are considered covered by the signature. | and all named headers and their values are considered covered by the | |||
| signature. | ||||
| There MAY be additional headers that are not listed in the list and | There MAY be additional headers that are not listed in the list and | |||
| are therefore not covered by the signature. The client MUST decide | are therefore not covered by the signature. The client MUST decide | |||
| whether or not to accept a request with these uncovered headers. | whether or not to accept a request with these uncovered headers. | |||
| 5. Example | ||||
| Example goes in here but will look like something like this | ||||
| (symmetric key case). | ||||
| 1) HTTP Request (plain) | ||||
| POST /request?b5=%3D%253D&a3=a&c%40=&a2=r%20b&c2 HTTP/1.1 | ||||
| Host: example.com | ||||
| 2) JWS protected JSON object | ||||
| {"typ":"pop", | ||||
| "alg":"HS256", | ||||
| "kid":"client12345@example.com"} | ||||
| . | ||||
| {"m":"POST", | ||||
| "u":"example.com", | ||||
| "p":"request", | ||||
| "q":[["a3", "b5", "a2"], "m2398f32i2o3roiu2313aa"], | ||||
| "ts":1300819380 | ||||
| } | ||||
| . | ||||
| dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk | ||||
| Figure 2: Message Flow. | ||||
| 6. IANA Considerations | 6. IANA Considerations | |||
| 6.1. The 'pop' OAuth Access Token Type | 6.1. The 'pop' OAuth Access Token Type | |||
| Section 11.1 of [RFC6749] defines the OAuth Access Token Type | Section 11.1 of [RFC6749] defines the OAuth Access Token Type | |||
| Registry and this document adds another token type to this registry. | Registry and this document adds another token type to this registry. | |||
| Type name: pop | Type name: pop | |||
| Additional Token Endpoint Response Parameters: (none) | Additional Token Endpoint Response Parameters: (none) | |||
| skipping to change at page 8, line 6 ¶ | skipping to change at page 9, line 4 ¶ | |||
| Registry and this document adds another token type to this registry. | Registry and this document adds another token type to this registry. | |||
| Type name: pop | Type name: pop | |||
| Additional Token Endpoint Response Parameters: (none) | Additional Token Endpoint Response Parameters: (none) | |||
| HTTP Authentication Scheme(s): Proof-of-possession access token for | HTTP Authentication Scheme(s): Proof-of-possession access token for | |||
| use with OAuth 2.0 | use with OAuth 2.0 | |||
| Change controller: IETF | Change controller: IETF | |||
| Specification document(s): [[ this document ]] | Specification document(s): [[ this document ]] | |||
| 6.2. JSON Web Signature and Encryption Type Values Registration | 6.2. JSON Web Signature and Encryption Type Values Registration | |||
| This specification registers the "pop" type value in the IANA JSON | This specification registers the "pop" type value in the IANA JSON | |||
| Web Signature and Encryption Type Values registry | Web Signature and Encryption Type Values registry [RFC7515]: | |||
| [I-D.ietf-jose-json-web-signature]: | ||||
| o "typ" Header Parameter Value: "pop" | o "typ" Header Parameter Value: "pop" | |||
| o Abbreviation for MIME Type: None | o Abbreviation for MIME Type: None | |||
| o Change Controller: IETF | o Change Controller: IETF | |||
| o Specification Document(s): [[ this document ]] | o Specification Document(s): [[ this document ]] | |||
| 7. Security Considerations | 7. Security Considerations | |||
| skipping to change at page 8, line 38 ¶ | skipping to change at page 9, line 34 ¶ | |||
| This specification can be used with and without Transport Layer | This specification can be used with and without Transport Layer | |||
| Security (TLS). | Security (TLS). | |||
| Without TLS this protocol provides a mechanism for verifying the | Without TLS this protocol provides a mechanism for verifying the | |||
| integrity of requests, it provides no confidentiality protection. | integrity of requests, it provides no confidentiality protection. | |||
| Consequently, eavesdroppers will have full access to communication | Consequently, eavesdroppers will have full access to communication | |||
| content and any further messages exchanged between the client and the | content and any further messages exchanged between the client and the | |||
| resource server. This could be problematic when data is exchanged | resource server. This could be problematic when data is exchanged | |||
| that requires care, such as personal data. | that requires care, such as personal data. | |||
| When TLS is used then confidentiality can be ensured; this version of | When TLS is used then confidentiality of the transmission can be | |||
| the specification does, however, not provide the TLS channel binding | ensured between endpoints, including both the request and the | |||
| feature, which ensures that the TLS channel is cryptographically | response. The use of TLS in combination with the signed HTTP request | |||
| bound to the application layer protocol authentication defined in | mechanism is highly recommended to ensure the confidentiality of the | |||
| this document. | data returned from the protected resource. | |||
| The use of TLS in combination with the signed HTTP request mechanism | ||||
| is highly recommended to ensure the confidentiality of the user's | ||||
| data. | ||||
| 7.2. Authentication of Resource Servers | ||||
| This protocol allows clients to verify the authenticity of resource | ||||
| servers only when TLS is used. With TLS the resource server is | ||||
| authenticated as part of the TLS handshake. The mechanism described | ||||
| in this document does not provide any mechanism for the client to | ||||
| authenticate the resource server at the application layer. | ||||
| 7.3. Plaintext Storage of Credentials | ||||
| The mechanism described in this document works similar to many three | 7.2. Plaintext Storage of Credentials | |||
| party authentication and key exchange mechanisms. In order to | ||||
| compute the signature over the HTTP request, the client must have | ||||
| access to a key bound to the access token (in plaintext form). | ||||
| If an attacker were to gain access to these stored secrets at the | The mechanism described in this document works in a similar way to | |||
| client or (in case of symmetric keys) at the resource server he or | many three-party authentication and key exchange mechanisms. In | |||
| she would be able to perform any action on behalf of any client. | order to compute the signature over the HTTP request, the client must | |||
| have access to a key bound to the access token in plaintext form. If | ||||
| an attacker were to gain access to these stored secrets at the client | ||||
| or (in case of symmetric keys) at the resource server they would be | ||||
| able to perform any action on behalf of any client just as if they | ||||
| had stolen a bearer token. | ||||
| It is therefore paramount to the security of the protocol that the | It is therefore paramount to the security of the protocol that the | |||
| private keys associated with the access tokens are protected from | private keys associated with the access tokens are protected from | |||
| unauthorized access. | unauthorized access. | |||
| 7.4. Entropy of Keys | 7.3. Entropy of Keys | |||
| Unless TLS is used between the client and the resource server, | Unless TLS is used between the client and the resource server, | |||
| eavesdroppers will have full access to requests sent by the client. | eavesdroppers will have full access to requests sent by the client. | |||
| They will thus be able to mount off-line brute-force attacks to | They will thus be able to mount off-line brute-force attacks to | |||
| recover the session key or private key used to compute the keyed | attempt recovery of the session key or private key used to compute | |||
| message digest or digital signature, respectively. | the keyed message digest or digital signature, respectively. | |||
| This specification assumes that the keying material for use with the | This specification assumes that the key used herein has been | |||
| described HTTP signing mechanism has been distributed via other | distributed via other mechanisms, such as | |||
| mechanisms, such as [I-D.bradley-oauth-pop-key-distribution]. Hence, | [I-D.ietf-oauth-pop-key-distribution]. Hence, it is the | |||
| it is the responsibility of the authorization server and or the | responsibility of the authorization server and or the client to be | |||
| client to be careful when generating fresh and unique keys with | careful when generating fresh and unique keys with sufficient entropy | |||
| sufficient entropy to resist such attacks for at least the length of | to resist such attacks for at least the length of time that the | |||
| time that the session keys (and the access tokens) are valid. | session keys (and the access tokens) are valid. | |||
| For example, if the key bound to the access token is valid for one | For example, if the key bound to the access token is valid for one | |||
| day, authorization servers must ensure that it is not possible to | day, authorization servers must ensure that it is not possible to | |||
| mount a brute force attack that recovers that key in less than one | mount a brute force attack that recovers that key in less than one | |||
| day. Of course, servers are urged to err on the side of caution, and | day. Of course, servers are urged to err on the side of caution, and | |||
| use the longest key length reasonable. | use the longest key length possible within reason. | |||
| 7.5. Denial of Service | 7.4. Denial of Service | |||
| This specification includes a number of features which may make | This specification includes a number of features which may make | |||
| resource exhaustion attacks against resource servers possible. For | resource exhaustion attacks against resource servers possible. For | |||
| example, a resource server may need to need to the resource server | example, a resource server may need to process the incoming request, | |||
| has to process the incoming request, verify the access token, perform | verify the access token, perform signature verification, and might | |||
| signature verification, and might have (in certain circumstances) | (in certain circumstances) have to consult back-end databases or the | |||
| consult back-end databases or the authorization server before | authorization server before granting access to the protected | |||
| granting access to the protected resource. | resource. Many of these actions are shared with bearer tokens, but | |||
| the additional cryptographic overhead of validating the signed | ||||
| request needs to be taken into consideration with deployment of this | ||||
| specification. | ||||
| An attacker may exploit this to perform a denial of service attack by | An attacker may exploit this to perform a denial of service attack by | |||
| sending a large number of invalid requests to the server. The | sending a large number of invalid requests to the server. The | |||
| computational overhead of verifying the keyed message digest alone | computational overhead of verifying the keyed message digest alone is | |||
| is, however, not sufficient to mount a denial of service attack since | not likely sufficient to mount a denial of service attack. To help | |||
| keyed message digest functions belong to the computationally fastest | combat this, it is RECOMMENDED that the protected resource validate | |||
| cryptographic algorithms. The situation may, however, be different | the access token (contained in the "at" member of the signed | |||
| when using asymmetric cryptography, which is also supported by the | structure) before performing any cryptographic verification | |||
| JWS. | calculations. | |||
| 7.6. Protecting HTTP Header Fields | 7.5. Validating the integrity of HTTP Headers and Query Parameters | |||
| This specification provides flexibility for selectively protecting | This specification provides flexibility for selectively validating | |||
| header fields and even the body of the message. Since all components | the integrity of header fields and message bodies. Since all | |||
| of the HTTP request are only optionally protected by this method, and | components of the HTTP request are only optionally validated by this | |||
| even some components may be protected only in part (e.g., some | method, and even some components may be validated only in part (e.g., | |||
| headers but not others) it is up to application developers to verify | some headers but not others) it is up to protected resource | |||
| that any parameters in a request are actually covered by the | developers to verify that any vital parameters in a request are | |||
| signature. | actually covered by the signature. | |||
| The application verifying this signature MUST NOT assume that any | The application verifying this signature MUST NOT assume that any | |||
| particular parameter is appropriately covered by the signature. Any | particular parameter is appropriately covered by the signature unless | |||
| it is included in the signed structure and the hash is verified. Any | ||||
| applications that are sensitive of header or query parameter order | applications that are sensitive of header or query parameter order | |||
| MUST verify the order of the parameters on their own. The | MUST verify the order of the parameters on their own. The | |||
| application MUST also compare the values in the JSON container with | application MUST also compare the values in the JSON container with | |||
| the actual parameters received with the HTTP request. Failure to | the actual parameters received with the HTTP request (using a direct | |||
| make this comparison will render the signature mechanism useless. | comparison or a hash calculation, as appropriate). Failure to make | |||
| this comparison will render the signature mechanism useless for | ||||
| protecting these elements. | ||||
| 8. Acknowledgements | The behavior of repeated query parameters or repeated HTTP headers is | |||
| undefined by this specification. If a header or query parameter is | ||||
| repeated on either the outgoing request from the client or the | ||||
| incoming request to the protected resource, that query parameter or | ||||
| header name MUST NOT be covered by the hash and signature. [[ Note to | ||||
| the WG: is this something we need to cover? ]] | ||||
| The authors acknowledge the OAuth Working Group and submit this draft | This specification records the order in which query parameters and | |||
| for feedback and input into the ongoing work of signed HTTP requests | headers are hashed, but it does not guarantee that order is preserved | |||
| for the interaction between clients and resource servers. | between the client and protected resource. | |||
| 9. References | 8. Privacy Considerations | |||
| 9.1. Normative References | This specification addresses machine to machine communications and | |||
| raises no privacy considerations beyond existing OAuth transactions. | ||||
| [I-D.ietf-jose-json-web-signature] | 9. Acknowledgements | |||
| Jones, M., Bradley, J., and N. Sakimura, "JSON Web | ||||
| Signature (JWS)", draft-ietf-jose-json-web-signature-41 | The authors thank the OAuth Working Group for input into this work. | |||
| (work in progress), January 2015. | ||||
| 10. Normative References | ||||
| [I-D.ietf-oauth-pop-architecture] | ||||
| Hunt, P., Richer, J., Mills, W., Mishra, P., and H. | ||||
| Tschofenig, "OAuth 2.0 Proof-of-Possession (PoP) Security | ||||
| Architecture", draft-ietf-oauth-pop-architecture-07 (work | ||||
| in progress), December 2015. | ||||
| [I-D.ietf-oauth-pop-key-distribution] | ||||
| Bradley, J., Hunt, P., Jones, M., and H. Tschofenig, | ||||
| "OAuth 2.0 Proof-of-Possession: Authorization Server to | ||||
| Client Key Distribution", draft-ietf-oauth-pop-key- | ||||
| distribution-02 (work in progress), October 2015. | ||||
| [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate | [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate | |||
| Requirement Levels", BCP 14, RFC 2119, March 1997. | Requirement Levels", BCP 14, RFC 2119, | |||
| DOI 10.17487/RFC2119, March 1997, | ||||
| <http://www.rfc-editor.org/info/rfc2119>. | ||||
| [RFC6749] Hardt, D., "The OAuth 2.0 Authorization Framework", RFC | [RFC6749] Hardt, D., Ed., "The OAuth 2.0 Authorization Framework", | |||
| 6749, October 2012. | RFC 6749, DOI 10.17487/RFC6749, October 2012, | |||
| <http://www.rfc-editor.org/info/rfc6749>. | ||||
| [RFC6750] Jones, M. and D. Hardt, "The OAuth 2.0 Authorization | [RFC6750] Jones, M. and D. Hardt, "The OAuth 2.0 Authorization | |||
| Framework: Bearer Token Usage", RFC 6750, October 2012. | Framework: Bearer Token Usage", RFC 6750, | |||
| DOI 10.17487/RFC6750, October 2012, | ||||
| <http://www.rfc-editor.org/info/rfc6750>. | ||||
| 9.2. Informative References | [RFC7159] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data | |||
| Interchange Format", RFC 7159, DOI 10.17487/RFC7159, March | ||||
| 2014, <http://www.rfc-editor.org/info/rfc7159>. | ||||
| [I-D.bradley-oauth-pop-key-distribution] | [RFC7515] Jones, M., Bradley, J., and N. Sakimura, "JSON Web | |||
| Bradley, J., Hunt, P., Jones, M., and H. Tschofenig, | Signature (JWS)", RFC 7515, DOI 10.17487/RFC7515, May | |||
| "OAuth 2.0 Proof-of-Possession: Authorization Server to | 2015, <http://www.rfc-editor.org/info/rfc7515>. | |||
| Client Key Distribution", draft-bradley-oauth-pop-key- | ||||
| distribution-01 (work in progress), June 2014. | ||||
| [I-D.hunt-oauth-pop-architecture] | [RFC7519] Jones, M., Bradley, J., and N. Sakimura, "JSON Web Token | |||
| Hunt, P., Richer, J., Mills, W., Mishra, P., and H. | (JWT)", RFC 7519, DOI 10.17487/RFC7519, May 2015, | |||
| Tschofenig, "OAuth 2.0 Proof-of-Possession (PoP) Security | <http://www.rfc-editor.org/info/rfc7519>. | |||
| Architecture", draft-hunt-oauth-pop-architecture-02 (work | ||||
| in progress), June 2014. | [RFC7662] Richer, J., Ed., "OAuth 2.0 Token Introspection", | |||
| RFC 7662, DOI 10.17487/RFC7662, October 2015, | ||||
| <http://www.rfc-editor.org/info/rfc7662>. | ||||
| Authors' Addresses | Authors' Addresses | |||
| Justin Richer (editor) | Justin Richer (editor) | |||
| Email: ietf@justin.richer.org | Email: ietf@justin.richer.org | |||
| John Bradley | John Bradley | |||
| Ping Identity | Ping Identity | |||
| End of changes. 69 change blocks. | ||||
| 253 lines changed or deleted | 323 lines changed or added | |||
This html diff was produced by rfcdiff 1.48. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ | ||||