Subject: [apps-discuss] HTTP MAC Authentication Scheme

From: Eran Hammer-Lahav <[email-masked]>
Date: Mon, 9 May 2011 12:22:23 -0700

(Please discuss this draft on the Apps-Discuss <[email-masked]> mailing list)

http://tools.ietf.org/html/draft-hammer-oauth-v2-mac-token

The draft includes:

* An HTTP authentication scheme using a MAC algorithm to authenticate requests (via a pre-arranged MAC key).
* An extension to the Set-Cookie header, providing a method for associating a MAC key with a session cookie.
* An OAuth 2.0 binding, providing a method of returning MAC credentials as an access token.

Some background: OAuth 1.0 introduced an HTTP authentication scheme using HMAC for authenticating an HTTP request with partial cryptographic protection of the HTTP request (namely, the request URI, host, and port). The OAuth 1.0 scheme was designed for delegation-based use cases, but is widely "abused" for simple client-server authentication (the poorly named 'two-legged' use case). This functionality has been separated from OAuth 2.0 and has been reintroduced as a standalone, generally applicable HTTP authentication scheme called MAC.

Comments and feedback is greatly appreciated.

EHL

---

From: Nico Williams <[email-masked]>
Date: Mon, 9 May 2011 15:03:11 -0500

On Mon, May 9, 2011 at 2:39 PM, Paul Hoffman <[email-masked]> wrote:
> Of interest to some here.

Indeed.  My GSS-REST proposal uses something like this too.

Regarding the question of when to include a hash of the body in the
normalized request string that gets MACed... If one is using TLS, then
I suggest adding the TLS channel binding into the MAC input string and
drop the body hash.  This will speed up operation, since there's no
need to hash the body (think of the performance impact of hashing the
request body in an implementation that uses sendfile()!).

I don't see the point of attempting to provide only partial integrity
protection (e.g., the draft doesn't say to include ever request header
into the MAC input) if there's no TLS.  In fact, I don't see the point
of not using TLS, but if TLS avoidance is desired then all of the
request (minus the MAC) and response should be covered by the MAC.

The response headers also should get a MAC.

Using channel binding means that the MAC input string can be much
smaller -- it need only be fresh if the TLS CB type is
tls-server-end-point.  If the CB type is tls-unique then no nonce nor
credential age elements are needed to establish freshness.  And back
to the tls-server-end-point case, if the freshness element is a
sequence number then the MACs can be pre-computed, with a small
sliding window (implemented as a small bitmap and highest number seen
state elements).

Finally, presumably it's the application that generates and validates
the MACs, not HTTP itself.  Correct?

Nico
--

---

From: Eran Hammer-Lahav <[email-masked]>
Date: Mon, 9 May 2011 13:29:36 -0700

Hi Nico,

> -----Original Message-----
> From: [email-masked] [mailto:apps-discuss-
> [email-masked]] On Behalf Of Nico Williams
> Sent: Monday, May 09, 2011 1:03 PM

> normalized request string that gets MACed... If one is using TLS, then I
> suggest adding the TLS channel binding into the MAC input string and drop
> the body hash.  This will speed up operation, since there's no need to hash
> the body (think of the performance impact of hashing the request body in an
> implementation that uses sendfile()!).

It is still not clear when hashing the body is really important, and if this should be just an optional feature or something that is required. If it is optional, it is not clear how the server should indicate to the client that it is required for any particular protected resource. We're still debating that and waiting for some deployment experience to guide us.

> I don't see the point of attempting to provide only partial integrity protection
> (e.g., the draft doesn't say to include ever request header into the MAC
> input) if there's no TLS.  In fact, I don't see the point of not using TLS, but if
> TLS avoidance is desired then all of the request (minus the MAC) and
> response should be covered by the MAC.

The point is to be practical given the target audience and use cases we have for this: web developers.

We have 3 years of experience asking web developers to perform request normalization and the results are pretty sad. OAuth 1.0 includes a pretty simple normalization of the request URI which ended up being a huge problem for many developers. If someone can come up with a simple way to canonicalize an HTTP request in a way that works with proxies and other intermediaries, and is easy to implement and debug, I'm happy to reconsider.
 
> The response headers also should get a MAC.

We're considering adding response verification, but not sure where to put it.

> Using channel binding means that the MAC input string can be much smaller -
> - it need only be fresh if the TLS CB type is tls-server-end-point.  If the CB
> type is tls-unique then no nonce nor credential age elements are needed to
> establish freshness.  And back to the tls-server-end-point case, if the
> freshness element is a sequence number then the MACs can be pre-
> computed, with a small sliding window (implemented as a small bitmap and
> highest number seen state elements).

Channel binding is hard to implement the way most web frameworks are used, as well as how browsers manage their stack. Also, lack of TLS is the main driver behind this proposal.

> Finally, presumably it's the application that generates and validates the
> MACs, not HTTP itself.  Correct?

Not sure what you mean, but this operates just like HTTP Basic and Digest in terms of its relation to HTTP.

EHL

---

From: Chris Bentzel <[email-masked]>
Date: Mon, 9 May 2011 21:00:02 -0400

> (Please discuss this draft on the Apps-Discuss <[email-masked]>

Should there be support for more headers in the Normalized Request String
[Section 3.3.1] to minimize MITM attacks? Could this be done on all
non-hop-by-hop headers? One concern is reordering of headers by
middle-boxes.

Should the body hash be a separate header from the Authorization header?
This may allow a User-Agent to do a Chunked-Encoding POST with a trailing
header containing the body hash, preventing the need to buffer all of the
body in the User-Agent before sending over the wire. However, it would lead
to some duplication of the parameters included in the Authorization header.

---

From: Eran Hammer-Lahav <[email-masked]>
Date: Mon, 9 May 2011 18:12:28 -0700

Hi Chris,

There is no good way to include headers in the normalized request string. Anything we've tried was just impractical for web adoption. Coming up with a canonicalization logic for HTTP headers that can survive all the allowed manipulations, and does not require repeating the headers in some encoded blog (say, base64 everything that is included in the MAC and include that blog with the request), is just too hard and error prone. It requires hard coding rules for each header given the number of exceptions in format and rules.

As for the body hash, we're looking for a way to make it useful for form-encoded bodies and API calls. It isn't really meant for large file uploads. We're trying to implement it in the browser and will make decisions based on that experience.

EHL

From: [email-masked] [mailto:[email-masked]] On Behalf Of Chris Bentzel
Sent: Monday, May 09, 2011 6:00 PM
To: [email-masked]
Subject: Re: [apps-discuss] HTTP MAC Authentication Scheme

On Mon, May 9, 2011 at 3:22 PM, Eran Hammer-Lahav <[email-masked]<mailto:[email-masked]>> wrote:
(Please discuss this draft on the Apps-Discuss <[email-masked]<mailto:[email-masked]>> mailing list)

Should there be support for more headers in the Normalized Request String [Section 3.3.1] to minimize MITM attacks? Could this be done on all non-hop-by-hop headers? One concern is reordering of headers by middle-boxes.

Should the body hash be a separate header from the Authorization header? This may allow a User-Agent to do a Chunked-Encoding POST with a trailing header containing the body hash, preventing the need to buffer all of the body in the User-Agent before sending over the wire. However, it would lead to some duplication of the parameters included in the Authorization header.

---

From: Chris Bentzel <[email-masked]>
Date: Mon, 9 May 2011 21:22:56 -0400

On Mon, May 9, 2011 at 9:12 PM, Eran Hammer-Lahav <[email-masked]>wrote:

>
> As for the body hash, we’re looking for a way to make it useful for
> form-encoded bodies and API calls. It isn’t really meant for large file
> uploads. We’re trying to implement it in the browser and will make decisions
> based on that experience.
>

This may be reasonable. auth-int on Digest is not supported by many browsers
due to the buffering concerns. The MAC spec seems to allow the client to
choose whether it wants body integrity on a per-request basis, so some
heuristic based on body size might be reasonable given your use case.

---

From: Nico Williams <[email-masked]>
Date: Tue, 10 May 2011 01:45:30 -0500

> It is still not clear when hashing the body is really important, and if this should be just an optional feature or something that is required. If it is optional, it is not clear how the server shou…

See below.

> The point is to be practical given the target audience and use cases we have for this: web developers.

Surely not.  Surely the point is to make some attack more difficult.
Yes, surely it's nice to make it easy for developers to use it, but
that's a secondary issue.  The primary issue, what I'm not getting
from the I-D, is what you're trying to protect against.

"What is your threat model?"

Nico
--

---

From: Eran Hammer-Lahav <[email-masked]>
Date: Tue, 10 May 2011 00:06:22 -0700

> From: Nico Williams [mailto:[email-masked]]
> Sent: Monday, May 09, 2011 11:46 PM
> To: Eran Hammer-Lahav
> Cc: Apps Discuss; [email-masked]
> Subject: Re: [apps-discuss] [saag] Fwd: HTTP MAC Authentication Scheme
> 
> >> normalized request string that gets MACed... If one is using TLS,
> >> then I suggest adding the TLS channel binding into the MAC input
> >> string and drop the body hash.  This will speed up operation, since
> >> there's no need to hash the body (think of the performance impact of
> >> hashing the request body in an implementation that uses sendfile()!).
> >
> > It is still not clear when hashing the body is really important, and if this
> should be just an optional feature or something that is required. If it is
> optional, it is not clear how the server should indicate to the client that it is
> required for any particular protected resource. We're still debating that and
> waiting for some deployment experience to guide us.
> 
> See below.
> 
> >> protection (e.g., the draft doesn't say to include ever request
> >> header into the MAC
> >> input) if there's no TLS.  In fact, I don't see the point of not
> >> using TLS, but if TLS avoidance is desired then all of the request
> >> (minus the MAC) and response should be covered by the MAC.
> >
> Yes, surely it's nice to make it easy for developers to use it, but that's a
> secondary issue.  The primary issue, what I'm not getting from the I-D, is
> what you're trying to protect against.
> 

An eavesdropper grabbing plaintext credentials and using them to gain access to protected resources. That's 99% of it, with the other 1% being that sending plaintext credentials over TLS can still leak due to incorrect implementation, or attacks on dynamic configuration, leading the client to send its plaintext credentials over TLS to the wrong server.

EHL

---

From: Nico Williams <[email-masked]>
Date: Tue, 10 May 2011 02:28:28 -0500

> An eavesdropper grabbing plaintext credentials and using them to gain access to protected resources. That's 99% of it, with the other 1% being that sending plaintext credentials over TLS can still…

That's what I thought.  If you add channel binding (meaning, to make
it real simple: add the server's certificate, or hash thereof, to the
MAC inputs -- the server cert is available in at least some JavaScript
implementations, like Firefox's) then you'll avoid those attacks that
you mention when using TLS.

It's not clear to me if you want to allow use of this MAC without
using TLS.  From the above I guess so, since the MAC alone will take
care of the eavesdroppers.

Nico
--

---

From: Nico Williams <[email-masked]>
Date: Fri, 20 May 2011 15:24:42 -0500

Additional comments:

 - Using nonces for replay protection is heavy-duty.  It is difficult
to implement a reliable, secure, high-performance replay cache.  (It
is easy to implement just a high-performance replay cache: use
memcache.)

   I recommend an option to use sequence numbers at the server's
choice, understanding, of course, that requests will not be received
in sequence.  The use of a sliding sequence number window makes it
possible to do at least as well as when using nonce, and probably
faster while still being secure.

 - In an open wifi environment active attacks may not be very
difficult, thus an option to secure more than just a handful of bits
from the request, would be nice (all of the request and all of the
response, say).  The hard part is how to decide when to use one or the
other.  Ideally browsers can request more protection when the network
is reconfigured such that there's one or more clear wifi interfaces.

Nico
--

---

From: Eran Hammer-Lahav <[email-masked]>
Date: Fri, 20 May 2011 14:18:21 -0700

> Sent: Friday, May 20, 2011 1:25 PM
> To: Eran Hammer-Lahav
> Cc: [email-masked]; Ben Adida; [email-masked]; OAuth WG; Adam
> Barth ([email-masked]); HTTP Working Group
>  - Using nonces for replay protection is heavy-duty.  It is difficult to
> implement a reliable, secure, high-performance replay cache.  (It is easy to
> implement just a high-performance replay cache: use
> memcache.)
> 
>    I recommend an option to use sequence numbers at the server's choice,
> understanding, of course, that requests will not be received in sequence.
> The use of a sliding sequence number window makes it possible to do at
> least as well as when using nonce, and probably faster while still being
> secure.

We switched to use time since credentials were issued. This should be pretty easy to implement if you really need reply protection by using a small window (clock sync is no longer a problem, just the delay in getting the credentials to the client, which should be a small window).

>  - In an open wifi environment active attacks may not be very difficult, thus
> an option to secure more than just a handful of bits from the request, would
> be nice (all of the request and all of the response, say).  The hard part is how
> to decide when to use one or the other.  Ideally browsers can request more
> protection when the network is reconfigured such that there's one or more
> clear wifi interfaces.

There is just no easy way to do that. If you need more, use TLS.

EHL

---

From: Nico Williams <[email-masked]>
Date: Fri, 20 May 2011 16:31:52 -0500

> We switched to use time since credentials were issued. This should be pretty easy to implement if you really need reply protection by using a small window (clock sync is no longer a problem, just t…

Kerberos has had an option to use time or sequence numbers for a long
time.  We've learned a few things from this experience.

For a memcache-type implementation, timestamps are probably best
because maintaining a sequence number window in memcache,
synchronized, would be a pain, if not impossible.

Other replay cache implementations would likely do better using
sequence numbers, especially when they have a small sequence number
window per-session.

And, of course, memcache isn't going to be durable (but probably it
will be good enough in many cases).  If you set a skew window to be
tight on the future side, then you can compensate for this if you can
detect loss of replay data (hmmm, not likely with memcache, eh?).

One big gotcha to be aware of:

 - Some clocks have lousy resolution, leading to easily repeated
values in high-rate environments.  One fix is to add resolution on the
wire and use random numbers for the unused precision bits.  Another
solution is to not use time.

My advice is that you allow the server to select which of timestamps
or sequence numbers to use.

Also, I strongly recommend that you specify replay cache semantics in
some detail.  Think of the Kerberos V5 replay cache semantics.

> There is just no easy way to do that. If you need more, use TLS.

But even then you need to know when to use TLS.  TLS doesn't solve the
problem when you're trying to solve problems without introducing TLS
in the first place.  This is a serious problem.  You think you're
fixing one problem (cookie theft by passive attackers on open
networks) and you're very likely only making things somewhat harder
for the attacker -- we need to be very careful that the attacker can't
just automate active attacks and still win.

Nico
--

---

From: Mark Nottingham <[email-masked]>
Date: Wed, 1 Jun 2011 09:57:19 +1000

Hi,

Reading draft -05.

The "normalized request string" contains the request-URI and values extracted from the Host header. Be aware that intermediaries can and do change these; e.g., they may change an absolute URI to a relative URI in the request-line, without affecting the semantics of the request. See [1] for details (it covers other problematic conditions too).

It would be more robust to calculate an effective request URI, as in [2].

Also, if you include a hash of the request body, you really need to include a hash of the body media type.

Generally, I think that people can and will want to include other headers; just because *some* developers can't get this right doesn't mean we should preclude *all* developers from doing it. It'd be really nice to see this either leverage DOSETA [3][4], or at least offer a clean transition path to it.

Regards,

1. http://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-14#section-4.1.2
2. http://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-14#section-4.3
3. http://tools.ietf.org/html/draft-crocker-dkim-doseta-00
4. http://tools.ietf.org/html/draft-crocker-doseta-base-02

On 10/05/2011, at 5:22 AM, Eran Hammer-Lahav wrote:

> Some background: OAuth 1.0 introduced an HTTP authentication scheme using HMAC for authenticating an HTTP request with partial cryptographic protection of the HTTP request (namely, the request URI, host, and port). The OAuth 1.0 scheme was designed for delegation-based use cases, but is widely “abused” for simple client-server authentication (the poorly named ‘two-legged’ use case). This functionality has been separated from OAuth 2.0 and has been reintroduced as a standalone, generally applicable HTTP authentication scheme called MAC.
>  
> _______________________________________________
> apps-discuss mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/apps-discuss

--
Mark Nottingham   http://www.mnot.net/