Internet DRAFT - draft-eaton-oauth-bodyhash

draft-eaton-oauth-bodyhash






Network Working Group                                           B. Eaton
Internet-Draft                                                    Google
Intended status: Standards Track                    E. Hammer-Lahav, Ed.
Expires: October 13, 2009                                         Yahoo!
                                                          April 11, 2009


                        OAuth Request Body Hash
                     draft-eaton-oauth-bodyhash-00

Status of this Memo

   This Internet-Draft is submitted to IETF in full conformance with the
   provisions of BCP 78 and BCP 79.

   Internet-Drafts are working documents of the Internet Engineering
   Task Force (IETF), its areas, and its working groups.  Note that
   other groups may also distribute working documents as Internet-
   Drafts.

   Internet-Drafts are draft documents valid for a maximum of six months
   and may be updated, replaced, or obsoleted by other documents at any
   time.  It is inappropriate to use Internet-Drafts as reference
   material or to cite them other than as "work in progress."

   The list of current Internet-Drafts can be accessed at
   http://www.ietf.org/ietf/1id-abstracts.txt.

   The list of Internet-Draft Shadow Directories can be accessed at
   http://www.ietf.org/shadow.html.

   This Internet-Draft will expire on October 13, 2009.

Copyright Notice

   Copyright (c) 2009 IETF Trust and the persons identified as the
   document authors.  All rights reserved.

   This document is subject to BCP 78 and the IETF Trust's Legal
   Provisions Relating to IETF Documents in effect on the date of
   publication of this document (http://trustee.ietf.org/license-info).
   Please review these documents carefully, as they describe your rights
   and restrictions with respect to this document.

Abstract

   This specification extends the OAuth signature to include integrity
   checks on HTTP request bodies with content types other than



Eaton & Hammer-Lahav    Expires October 13, 2009                [Page 1]

Internet-Draft           OAuth Request Body Hash              April 2009


   "application/x-www-form-urlencoded".


Table of Contents

   1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  3
   2.  Notation and Conventions . . . . . . . . . . . . . . . . . . .  3
   3.  The oauth_body_hash Parameter  . . . . . . . . . . . . . . . .  4
     3.1.  Hash Algorithm . . . . . . . . . . . . . . . . . . . . . .  4
     3.2.  Hash Calculation . . . . . . . . . . . . . . . . . . . . .  4
   4.  Changes to OAuth Request Signing . . . . . . . . . . . . . . .  4
     4.1.  Sending Requests . . . . . . . . . . . . . . . . . . . . .  4
       4.1.1.  When to Include the Body Hash  . . . . . . . . . . . .  4
       4.1.2.  Adding oauth_body_hash to Requests . . . . . . . . . .  5
     4.2.  Verifying Requests . . . . . . . . . . . . . . . . . . . .  5
       4.2.1.  When to Verify the Hash  . . . . . . . . . . . . . . .  6
       4.2.2.  Verifying the Hash . . . . . . . . . . . . . . . . . .  6
   5.  IANA Considerations  . . . . . . . . . . . . . . . . . . . . .  6
   6.  Security Considerations  . . . . . . . . . . . . . . . . . . .  6
     6.1.  Only Trust What is Signed  . . . . . . . . . . . . . . . .  6
     6.2.  Deprecation of SHA-1 . . . . . . . . . . . . . . . . . . .  7
   Appendix A.   Examples . . . . . . . . . . . . . . . . . . . . . .  7
   Appendix A.1. Example PUT Request  . . . . . . . . . . . . . . . .  7
   Appendix A.2. Example GET Request  . . . . . . . . . . . . . . . .  8
   Appendix B.   Obtaining the HTTP Entity Body . . . . . . . . . . .  9
   Appendix C.   Unkeyed vs Keyed Hash Algorithms . . . . . . . . . .  9
   Appendix D.   Preventing Removal of Request Bodies . . . . . . . .  9
   Appendix E.   Acknowledgements . . . . . . . . . . . . . . . . . . 10
   7.  References . . . . . . . . . . . . . . . . . . . . . . . . . . 11
     7.1.  Normative References . . . . . . . . . . . . . . . . . . . 11
     7.2.  Informative References . . . . . . . . . . . . . . . . . . 11
   Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . . 11



















Eaton & Hammer-Lahav    Expires October 13, 2009                [Page 2]

Internet-Draft           OAuth Request Body Hash              April 2009


1.  Introduction

   The OAuth Core specification [OAuth Core 1.0] provides body integrity
   checking only for "application/x-www-form-urlencoded" request bodies.
   Other types of request bodies are left unsigned.  An eavesdropper or
   man-in-the-middle who captures a signed request URI may be able to
   forward or replay that URI with a different HTTP request body.  Nonce
   checking and the use of https can mitigate this risk, but may not be
   available in some environments.  Even when nonce checking and https
   are used, signing the request body provides an additional layer of
   defense.

   This specification describes a method to provide an integrity check
   on non-form-encoded request bodies.  The normal OAuth signature base
   string is enhanced by adding an additional parameter with the hash of
   the request body.  An unkeyed hash is used for the reasons described
   in Appendix C.

   This extension is forward compatible: Service Providers that have not
   implemented this extension can verify requests sent by Consumers that
   have implemented this extension.  If the Service Provider implements
   this specification the integrity of the body is guaranteed.  If the
   Service Provider does not check body signatures, the remainder of the
   request will still validate using the OAuth Core signature algorithm.

   This specification is only useful when cryptographic signatures are
   used.  The OAuth "PLAINTEXT" signature algorithm does not provide
   integrity checks for any portion of the request and is not supported
   by this specification.

   The use of this specification with versions of the OAuth protocol
   other than "1.0" is undefined.


2.  Notation and Conventions

   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
   document are to be interpreted as described in [RFC2119].

   Unless otherwise noted, this specification is written as a direct
   continuation of [OAuth Core 1.0], inheriting the definitions and
   guidelines set by it.

   To make the specification easier to read, HTTP entity-bodies
   following the encoding requirements of the
   "application/x-www-form-urlencoded" content-type as defined by
   [W3C.REC-html40-19980424] are simply referred to as form-encoded.



Eaton & Hammer-Lahav    Expires October 13, 2009                [Page 3]

Internet-Draft           OAuth Request Body Hash              April 2009


3.  The oauth_body_hash Parameter

3.1.  Hash Algorithm

   The body hash algorithm is determined by the OAuth signature method
   used:

   o  If the OAuth signature method is "HMAC-SHA1" or "RSA-SHA1", SHA1
      [RFC3174] MUST be used as the body hash algorithm.

   o  If the OAuth signature method is "PLAINTEXT", use of this
      specification provides no security benefit and is NOT RECOMMENDED.

   New OAuth signature method specifications SHOULD specify the hash
   algorithm used to generate the body hash.

3.2.  Hash Calculation

   The value of the oauth_body_hash parameter SHALL be set as follows:

   1.  The body hash value is calculated by executing the selected hash
       algorithm over the request body.  The request body is the entity
       body as defined in [RFC2616] section 7.2.  If the request does
       not have an entity body, the hash should be taken over the empty
       string.

   2.  The calculated body hash value is encoded using Base64 per
       [RFC2045].


4.  Changes to OAuth Request Signing

4.1.  Sending Requests

   OAuth Consumers include the oauth_body_hash parameter according to
   the rules described in this section, and continue to sign requests in
   the manner described by [OAuth Core 1.0] section 9.

4.1.1.  When to Include the Body Hash

   Not all requests should contain the oauth_body_hash parameter.

   o  OAuth Consumers SHOULD NOT include an oauth_body_hash parameter
      when making Request Token or Access Token OAuth requests.

   o  OAuth Consumers MUST NOT include an oauth_body_hash parameter on
      requests with form-encoded request bodies.  The presence or
      absence



Eaton & Hammer-Lahav    Expires October 13, 2009                [Page 4]

Internet-Draft           OAuth Request Body Hash              April 2009


   o  OAuth Consumers SHOULD include the oauth_body_hash parameter on
      all other requests.

   Some OAuth Service Providers have implemented Request Token and
   Access Token endpoints that reject requests that include unknown
   parameters.  Sending an oauth_body_hash parameter to such endpoints
   will cause protocol failures.  The oauth_body_hash parameter does not
   provide additional security for OAuth request token and access token
   requests since all of the protocol parameters are signed by the OAuth
   Core signature mechanism.  Omitting the parameter improves
   interoperability without reducing security.

   The presence or absence of the oauth_body_hash parameter is used to
   indicate to Service Providers how they should check the integrity of
   the request body.  If no oauth_body_hash parameter is present, that
   indicates that the request body is form-encoded and signed using the
   OAuth Core signature algorithm.  If the oauth_body_hash parameter is
   present, the body is signed according to this extension.  Including
   an oauth_body_hash on form-encoded requests would make it impossible
   for Service Providers to determine which body signing mechanism was
   used for the request.  This ambiguity would, in turn, allow the
   attack described in Appendix D.

4.1.2.  Adding oauth_body_hash to Requests

   To include the oauth_body_hash parameter in OAuth-authenticated
   requests, Consumers SHALL:

   1.  Determine whether the parameter should be included using the
       rules described in Section 4.1.1.

   2.  Calculate the body hash value as described in Section 3

   3.  Set the oauth_body_hash parameter to the obtained value.

   4.  Sign the request as per [OAuth Core 1.0] section 9.  The
       oauth_body_hash parameter MUST be included in the Signature Base
       String together with the other request parameters.

   5.  Transmit the oauth_body_hash parameter along with the other OAuth
       Protocol parameters in the signed OAuth request.

4.2.  Verifying Requests

   Service Providers verify the integrity of request bodies by verifying
   the OAuth signature as described in [OAuth Core 1.0] and also
   verifying the value of the oauth_body_hash parameter.




Eaton & Hammer-Lahav    Expires October 13, 2009                [Page 5]

Internet-Draft           OAuth Request Body Hash              April 2009


4.2.1.  When to Verify the Hash

   Service Providers MUST decide whether the oauth_body_hash parameter
   is necessary according to the rules described in Section 4.1.1.

   If the request MUST NOT have an oauth_body_hash parameter, Service
   Providers MUST verify that no oauth_body_hash parameter is present.
   In particular, any requests with a form-encoded content-type and an
   oauth_body_hash parameter MUST be rejected because of of the attack
   described in Appendix D.

   If the request should have an oauth_body_hash parameter but does not
   contain one, the request was sent by a Consumer that does not support
   this extension.  The integrity of the request body cannot be checked
   using this specification.  Service Providers MAY accept such requests
   for interoperability, or they MAY reject such requests in favor of
   security.

4.2.2.  Verifying the Hash

   If the Service Provider determines body hash verification is
   necessary, the Service Provider calculates the expected body hash for
   the request as described in Section 3.

   The Service Provider then compares the expected body hash with the
   value sent by the Consumer in the oauth_body_hash parameter.  If the
   values match, the body is intact and the request can proceed.

   If the values do not match, the request MUST be rejected.

   Rather than comparing text values, Service Providers MAY Base64
   decode (per [RFC2045]) the oauth_body_hash parameter and perform the
   comparison on the octets of the hash.  This reduces the risk of minor
   differences in URI encoding or Base64 encoding causing spurious
   integrity check failures.


5.  IANA Considerations

   This memo includes no request to IANA.


6.  Security Considerations

6.1.  Only Trust What is Signed

   Many factors besides the bytes of the request body can influence the
   interpretation of the body of the HTTP request.  For example, a



Eaton & Hammer-Lahav    Expires October 13, 2009                [Page 6]

Internet-Draft           OAuth Request Body Hash              April 2009


   content-type or content-encoding header can change the way a server
   handles an HTTP request.  This specification does not include an
   integrity check on the HTTP request headers.  OAuth deployments whose
   security could be impacted by an attacker who tampers with HTTP
   request headers should use other mechanisms (such as HTTPS) to
   protect the confidentiality and integrity of the entire HTTP request.

6.2.  Deprecation of SHA-1

   In [NIST 800-107] the NIST Computer Security Division has recommended
   that applications stop using SHA-1 for digital signatures.  As of the
   time of this writing, all of the cryptographic signature schemes
   defined for OAuth are based on SHA-1.  OAuth signature methods based
   on stronger hash functions need to be developed, and those signature
   methods will need to specify algorithms for calculating the
   oauth_body_hash as well.


Appendix A.  Examples

Appendix A.1.  Example PUT Request

   Sample HTTP request:

     PUT /resource HTTP/1.1
     Host: www.example.com
     Content-Type: text/plain
     Content-Length: 12

     Hello World!

   Base64 encoded SHA-1 hash of the body:

     Lve95gjOVATpfV8EL5X4nxwjKHE=

   Signature Base String (with some line breaks added for readability):

     PUT&http%3A%2F%2Fwww.example.com%2Fresource&oauth_body_hash%3D
     Lve95gjOVATpfV8EL5X4nxwjKHE%253D%26oauth_consumer_key%3Dconsum
     er%26oauth_nonce%3D10369470270925%26oauth_signature_method%3DH
     MAC-SHA1%26oauth_timestamp%3D1236874236%26oauth_token%3Dtoken%
     26oauth_version%3D1.0

   Signed request with body hash (with some line breaks added for
   readability):






Eaton & Hammer-Lahav    Expires October 13, 2009                [Page 7]

Internet-Draft           OAuth Request Body Hash              April 2009


     PUT /resource HTTP/1.1
     Host: www.example.com
     Authorization: OAuth realm="http%3A%2F%2Fwww.example.com",
         oauth_body_hash="Lve95gjOVATpfV8EL5X4nxwjKHE%3D",
         oauth_token="token",
         oauth_consumer_key="consumer",
         oauth_signature_method="HMAC-SHA1",
         oauth_timestamp="1236874155", oauth_nonce="10288510250934",
         oauth_version="1.0",
         oauth_signature="08bUFF%2Fjmp59mWB7cSgCYBUpJ0U%3D"
     Content-Type: text/plain
     Content-Length: 12

     Hello World!

Appendix A.2.  Example GET Request

   Sample HTTP request:

     GET /resource HTTP/1.1
     Host: www.example.com


   Base64 encoded SHA-1 hash of the (non-existent) body:

     2jmj7l5rSw0yVb/vlWAYkK/YBwk=

   Signature Base String (line breaks added for readability):

     GET&http%3A%2F%2Fwww.example.com%2Fresource&oauth_body_hash%3D2jmj7
     l5rSw0yVb%252FvlWAYkK%252FYBwk%253D%26oauth_consumer_key%3Dconsumer
     %26oauth_nonce%3D8628868109991%26oauth_signature_method%3DHMAC-SHA1
     %26oauth_timestamp%3D1238395022%26oauth_token%3Dtoken%26oauth_versi
     on%3D1.0

   Signed request with body hash (with some line breaks added for
   readability):

     GET /resource HTTP/1.1
     Host: www.example.com
     Authorization: OAuth realm="http%3A%2F%2Fwww.example.com",
         oauth_body_hash="2jmj7l5rSw0yVb/vlWAYkK/YBwk%3D",
         oauth_token="token",
         oauth_consumer_key="consumer",
         oauth_signature_method="HMAC-SHA1",
         oauth_timestamp="1236874155", oauth_nonce="10288510250934",
         oauth_version="1.0",
         oauth_signature="08bUFF%2Fjmp59mWB7cSgCYBUpJ0U%3D"



Eaton & Hammer-Lahav    Expires October 13, 2009                [Page 8]

Internet-Draft           OAuth Request Body Hash              April 2009


Appendix B.  Obtaining the HTTP Entity Body

   Not all programming platforms provide an easy mechanism to obtain the
   raw octets of the HTTP entity body.  Reading the entity body as raw
   octets may have side effects, such as inhibiting automatic character
   set conversion.  Some platforms do not allow direct access to the
   entity body at all if the content-type is application/
   x-www-form-urlencoded.  Transfer-encodings such as gzip also
   complicate implementation.  On the other hand, reading the entity
   body as text may perform lossy conversions that prevent recovery of
   the original octet stream in some situtations.  Character set
   conversions are not always one-to-one mappings, so solutions that
   rely on converting text back to the original octet stream are likely
   to fail in environments with multibyte characters.

   All of these factors, and others, can make it difficult to drop in a
   "verify-the-signature" filtering layer prior to other request
   processing.  The verification layer must consider the assumptions of
   downstream processing code on the state of the request body.

   Implementers of this specification should be aware of these
   difficulties and consider the best way to address them in their
   programming frameworks.


Appendix C.  Unkeyed vs Keyed Hash Algorithms

   This specification deliberately uses an unkeyed hash algorithm
   (SHA-1) to provide an integrity check on the body instead of a keyed
   hash algorithm such as HMAC-SHA1.  This decision was made because
   signing arbitrary octet streams is poor cryptographic hygiene.  It
   can lead to unexpected problems with cryptographic protocols.

   For example, consider a proxy that uses OAuth to add authentication
   information to requests sent by an untrusted third-party.  If the
   proxy signs arbitrary octet streams, the third-party can use the
   proxy as an oracle to forge authentication messages.

   Including the result of an unkeyed hash in the normal signature base
   string allows the proxy to add an integrity check on the original
   message without creating a signing oracle.


Appendix D.  Preventing Removal of Request Bodies

   This specification requires that Consumers not send the
   oauth_body_hash parameter on requests with form-encoded bodies, and
   requires that Service Providers reject requests that have form-



Eaton & Hammer-Lahav    Expires October 13, 2009                [Page 9]

Internet-Draft           OAuth Request Body Hash              April 2009


   encoded bodies and an oauth_body_hash parameter.  These restrictions
   are necessary in order to prevent a MITM from removing non-form-
   encoded request bodies.  The attack would work as follows:

   1.  Consumer signs a request with a non-form-encoded request body and
       includes a matching content-type header such as "application/
       json" or "text/plain".  The oauth_body_hash parameter is included
       as well.

   2.  MITM intercepts request and modifies the content-type of the
       request to be "application/x-www-form-urlencoded".  The MITM also
       removes the request body.  The request is then forwarded to the
       Service Provider.

   3.  The Service Provider receives the request and the signature
       validates according to the OAuth Core signature specification.

   4.  The Service Provider then needs to decide whether to check the
       oauth_body_hash value as well.  Since the request content-type is
       form-encoded, the Service Provider does not check the
       oauth_body_hash.

   5.  The removal of the body goes undetected.

   The impact of this attack is probably minimal.  The attacker can
   remove the request body, but cannot replace it with their own.  Stil,
   the goal of this specification is guaranteeing body integrity when
   both Consumers and Service Providers use the oauth_body_hash
   parameter.  Out of an excess of caution, this specification requires
   that Service Providers reject request that have both a form-encoded
   request body and an oauth_body_hash parameter.

   An alternate solution, requiring that Service Providers check the
   oauth_body_hash parameter even on form-encoded request bodies, was
   rejected due to implementation challenges.  Some web development
   frameworks block access to the raw entity body for form-encoded
   requests.


Appendix E.  Acknowledgements

   Several members of the community contributed valuable feedback and
   suggestions, including Allen Tom, Ben Laurie, Dirk Balfanz, George
   Fletcher, John Panzer, Louis Ryan, and Marc Worrell.


7.  References




Eaton & Hammer-Lahav    Expires October 13, 2009               [Page 10]

Internet-Draft           OAuth Request Body Hash              April 2009


7.1.  Normative References

   [OAuth Core 1.0]
              OAuth, OCW., "OAuth Core 1.0".

   [RFC2045]  Freed, N. and N. Borenstein, "Multipurpose Internet Mail
              Extensions (MIME) Part One: Format of Internet Message
              Bodies", RFC 2045, November 1996.

   [RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
              Requirement Levels", BCP 14, RFC 2119, March 1997.

   [RFC2616]  Fielding, R., Gettys, J., Mogul, J., Frystyk, H.,
              Masinter, L., Leach, P., and T. Berners-Lee, "Hypertext
              Transfer Protocol -- HTTP/1.1", RFC 2616, June 1999.

   [RFC3174]  Eastlake, D. and P. Jones, "US Secure Hash Algorithm 1
              (SHA1)", RFC 3174, September 2001.

   [W3C.REC-html40-19980424]
              Hors, A., Raggett, D., and I. Jacobs, "HTML 4.0
              Specification", World Wide Web Consortium
              Recommendation REC-html40-19980424, April 1998,
              <http://www.w3.org/TR/1998/REC-html40-19980424>.

7.2.  Informative References

   [NIST 800-107]
              Dang, Q., "Special Publication 800-107, Recommendation for
              Applications Using Approved Hash Algorithms".


Authors' Addresses

   Brian Eaton
   Google

   Email: beaton@google.com


   Eran Hammer-Lahav (editor)
   Yahoo!

   Email: eran@hueniverse.com
   URI:   http://hueniverse.com






Eaton & Hammer-Lahav    Expires October 13, 2009               [Page 11]