Subject: [OAUTH-WG] Token Access Authentication Scheme Draft

From: Eran Hammer-Lahav <[email-masked]>
Date: Mon, 7 Dec 2009 01:27:57 -0700

http://www.ietf.org/id/draft-hammer-http-token-auth-00.txt

This draft is my first attempt at defining a general purpose authentication scheme to fulfill the WG requirement to produce a scheme suitable for 2-legged authentication. It also supports the OAuth 3-legged use cases as discussed on the list. This draft is in very early stage and has been submitted early to help better facilitate the conversation.

It has been hard for us to discuss ideas without a concrete proposal. I hope this will help and motivate people to participate and provide feedback and new ideas. While there are many holes in the draft, it should be pretty easy to follow it.

Major changes from OAuth 1.0:

* New auth scheme with new parameter names
* Signature base string replaced with normalized request string, and now does not require *any* encoding
* Supports multiple token classes, authentication methods, and coverage scope

Main feedback requested:

* Initial impressions - this is particularly important to get. Does the draft make sense?
* Functionality - does it include all the requested/required functionality?
* Abstraction level - do the attributes provide the right level of configuration and choice?

Please refrain from editorial feedback at this point (grammar, typos, etc.), but do provide structural feedback.

I plan to push an updated version by Wed which will incorporate as much feedback as I can. I plan to ask for the WG to promote this draft to a WG item within 2 weeks.

Thanks,

EHL

---

From: Stephen Farrell <[email-masked]>
Date: Mon, 07 Dec 2009 10:54:31 +0000

> http://www.ietf.org/id/draft-hammer-http-token-auth-00.txt

I think that's a really good start & that the WG should
adopt it.

One thing that this suggests to me is that for cases
where the client and server do have a shared secret,
but are not running over TLS, (or where TLS is terminated
before the actual server), we could use that shared
secret to protect the response in a similar way to the
request.

I've no idea if folks think that'd be useful enough
to be worth doing or not (and I'd be a little leery of
it myself since it de-motivates turning on TLS), nor
whether it would belong in this spec or this WG, but
I think its worthwhile asking since I suspect that
compromised on-path proxies might become a more common
attack vector in future.

S.

> _______________________________________________
> OAuth mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/oauth
>

---

From: Eran Hammer-Lahav <[email-masked]>
Date: Mon, 7 Dec 2009 09:07:23 -0700

This has been proposed before in the security review for draft-hammer-oauth. It should be pretty easy to add. My concern would be that the web developers I know will never bother validating server responses.

EHL

> -----Original Message-----
> From: Stephen Farrell [mailto:[email-masked]]
> Sent: Monday, December 07, 2009 2:55 AM
> To: Eran Hammer-Lahav
> Cc: OAuth WG ([email-masked])
> Subject: Re: [OAUTH-WG] Token Access Authentication Scheme Draft
> 
> 
> Eran Hammer-Lahav wrote:
> I think that's a really good start & that the WG should adopt it.
> 
> One thing that this suggests to me is that for cases where the client and
> server do have a shared secret, but are not running over TLS, (or where TLS is
> terminated before the actual server), we could use that shared secret to
> protect the response in a similar way to the request.
> 
> I've no idea if folks think that'd be useful enough to be worth doing or not
> (and I'd be a little leery of it myself since it de-motivates turning on TLS), nor
> whether it would belong in this spec or this WG, but I think its worthwhile
> asking since I suspect that compromised on-path proxies might become a
> more common attack vector in future.
> 
> S.
> 
> 
> > This draft is my first attempt at defining a general purpose authentication
> scheme to fulfill the WG requirement to produce a scheme suitable for 2-
> legged authentication. It also supports the OAuth 3-legged use cases as
> discussed on the list. This draft is in very early stage and has been submitted
> early to help better facilitate the conversation.
> >
> > It has been hard for us to discuss ideas without a concrete proposal. I hope
> this will help and motivate people to participate and provide feedback and
> new ideas. While there are many holes in the draft, it should be pretty easy
> to follow it.
> >
> > I plan to push an updated version by Wed which will incorporate as much
> feedback as I can. I plan to ask for the WG to promote this draft to a WG item
> within 2 weeks.
> >
> > Thanks,
> >
> > EHL

---

From: Stephen Farrell <[email-masked]>
Date: Mon, 07 Dec 2009 16:14:43 +0000

> This has been proposed before in the security review for draft-hammer-oauth. It should be pretty easy to add. My concern would be that the web developers I know will never bother validating server…

That's a valid concern. Do you know why?

I could imagine some mixture of the following:

1. their current applications aren't sensitive enough to
   bother doing this
2. lack of tools/APIs to make it easy to verify responses
3. responses get mangled so often so you'd never get
   many that actually verify
4. something else

If #1 & #2 were the primary reasons I don't think those
should mean not taking this on (not that I'm yet arguing
that we should, I'm still just asking).

#3 however would be a bit of a killer, as, I suppose,
could #4:-)

S.

---

From: Brian Eaton <[email-masked]>
Date: Mon, 7 Dec 2009 23:05:27 -0800

> http://www.ietf.org/id/draft-hammer-http-token-auth-00.txt

I'm not a fan, for a couple of reasons.

The signature base string (section 8 in the draft) is still very
complex to describe and construct... and even with all that
complexity, I don't think it meets most of the use cases for
two-legged OAuth that were identified in earlier conversations about
why people are using OAuth signing [1].

I'd like to propose an alternative approach for OAuth message
authentication that focuses on providing a reusable signature base
string and meeting existing two-legged OAuth use cases.  This is
fairly close to SWT [2], but I think SWT has some warts [3] that need
fixing.

If there is general support/interest in this, I'm happy to write it up
more formally.  Here's an informal version:

An OAuth message signature is made up of three components, an
envelope, a message, and a signature.  The envelope and the message
are base64 encoded JSON objects.  The signature is a base64 encoded
byte string.  The encoding uses the web-safe base64 alphabet without
line feeds or padding described by RFC 4648 [4].  The three components
are joined with '.' characters.

The envelope field is a description of the payload.  It contains a
"name" field that identifies the key used to sign the message.  It
contains an "algorithm" field that identifies the signature algorithm
used to sign the message.  And it contains a timestamp (measured in
seconds since the epoch) and a nonce used to prevent replay attacks.
For example, the envelope might look like this:

{
    "name": "source.example.com",
    "algorithm": "RSA-SHA256",
    "timestamp": 1260253850,
    "nonce": "0437f743b5809"
}

The message field contains the payload of the signed message.  For
signing an HTTP request, the message contains a single field "url",
with a copy of the HTTP URL of the request:

{
    "url": "http://destination.example.com/resource?abcd=1234"
}

Signing messages besides HTTP requests, or extending the HTTP request
signature to cover additional components of the request, is trivial:
add new fields to the JSON payload of the message.

The signature base string is generated by concatentating the base64
encoded envelope and message.  First, the envelope is encoded.  For
the example above, the envelope becomes:

ewogICAgIm5hbWUi<elided>Cg

Next, the message is encoded.  For the example above, the message becomes:

ewogICAgIm5hbWUi<elided>Cg

The envelope and the message are then joined with a '.' character:

ewogICAgIm5hbWUi<elided>Cg.ewogICAgIm5hbWUi<elided>Cg

The resulting string is signed with the specified key and algorithm.
The signature is base64 encoded and appended to the envelope and
message.  For the example above:

ewogICAgIm5hbWUi<elided>Cg.ewogICAgIm5hbWUi<elided>Cg.qSSVPG3bTw5<elided>-YFab315w

The resulting signed token can then be embedded in an HTTP header:

Authorization: Token
ewogICAgIm5hbWUi<elided>Cg.ewogICAgIm5hbWUi<elided>Cg.qSSVPG3bTw5<elided>-YFab315w

Verification of the signature is trivial, because it does not require
reconstructing the signature base string or canonicalization of
values.  The exact data that was signed is present in the request.

Cheers,
Brian

[1] http://www.ietf.org/mail-archive/web/oauth/current/msg00530.html
[2] https://oauth-wrap-wg.googlegroups.com/web/SWT-v0.9.5.1.pdf
[3] https://groups.google.com/group/WRAP-WG/browse_thread/thread/a88135610e57b976
[4] http://tools.ietf.org/html/rfc4648#section-5

---

From: Eran Hammer-Lahav <[email-masked]>
Date: Tue, 8 Dec 2009 00:52:30 -0700

> From: Brian Eaton [mailto:[email-masked]]
> Sent: Monday, December 07, 2009 11:05 PM
> To: Eran Hammer-Lahav
> The signature base string (section 8 in the draft) is still very complex to
> describe and construct... and even with all that complexity, I don't think it
> meets most of the use cases for two-legged OAuth that were identified in
> earlier conversations about why people are using OAuth signing [1].

Can you list the use cases it doesn't meet? This is largely a cosmetic rewrite of 1.0 with the exception of directly supporting form-encoded parameters which is still being discussed. Your reference is to a post about mostly non-HTTP use cases.

> An OAuth message signature is made up of three components, an envelope,
> a message, and a signature.  The envelope and the message are base64
> encoded JSON objects.  The signature is a base64 encoded byte string.  The
> encoding uses the web-safe base64 alphabet without line feeds or padding
> described by RFC 4648 [4].  The three components are joined with '.'
> characters.

Requiring JSON parser is additional work for the client. Not much work, but more than just parsing an HTTP header which it has to do anyway.
 
> The envelope field is a description of the payload.  It contains a "name" field
> that identifies the key used to sign the message.  It contains an "algorithm"
> field that identifies the signature algorithm used to sign the message.  And it
> contains a timestamp (measured in seconds since the epoch) and a nonce
> used to prevent replay attacks.

Not sure what 'name' means. Is it a made up string by the server? Is it a well-defined certificate field?
 
> The message field contains the payload of the signed message.  For signing
> an HTTP request, the message contains a single field "url", with a copy of the
> HTTP URL of the request:
> 
> {

This requires normalization as HTTP requests don't actually have such a URL.

> reconstructing the signature base string or canonicalization of values.  The
> exact data that was signed is present in the request.

You are trading the server's need to reconstruct the normalized request string with the need to validate all the values contained. The server still has to compare the Host header, port, request URI, and everything else to what has been signed. Doesn't seem like a big difference.

The only fundamental difference here, beyond format, is that you are including what you are signing. Doing that, regardless of structure is a significant shift in how requests have been signed in 1.0. This is not a reason not to adopt such a proposal, but before considering the details of your idea, we need to discuss this first.

I am not crazy about using JSON here, but that's a matter of style. The real issue is if we want to include the normalized request string with the request. And you still have to provide the encoded token using an attribute. Only Basic Auth is allowed to violate the key="value" header rule.

EHL

---

From: Dan Winship <[email-masked]>
Date: Tue, 08 Dec 2009 13:59:31 -0500

> http://www.ietf.org/id/draft-hammer-http-token-auth-00.txt

OK, so I'm not familiar with OAuth in detail, and am reviewing this more
from the perspective of an HTTP client library author who will
eventually end up implementing the spec...

First off, I don't like the idea of having one new meta-scheme ("Token")
with multiple sub-schemes ("oauth", etc). I've already got code to allow
extensibility/pluggability at the scheme level (Basic, Digest, NTLM,
etc). I don't want to have a *second* extension point inside one of the
auth schemes. If there's going to be both OAuth and
SomeoneElsesTokenBasedAuth, I'd rather have them as separate top-level
schemes, even if the implementations ended up sharing a lot of
parsing/digest-computing code between them.

If you really think it's important to have a generic "token" framework
with OAuth as just one implementation of it, a nicer way would be to
remove the "class" attribute and the "Token" scheme name, and just say
that each token auth subtype will define its own scheme name. So instead of

     WWW-Authenticate: Token class="oauth",
                             methods="hmac-sha-1 hmac-sha-256",
                             timestamp="137131190"

you'd have

     WWW-Authenticate: OAuth methods="hmac-sha-1 hmac-sha-256",
                             timestamp="137131190"

but most of the rest of the spec would be unchanged. (OK, reading back
through old threads I see that part of the goal was to not have it be
named "OAuth". But you could just use "OAuth2" or "OAuthToken" or
something.)

But then again, is there any evidence that anyone besides OAuth will
ever use the Token scheme? (And if so, that the existing definition of
the Token parameters will be right for them?)

Moving on...

If Token/OAuth is not intended for use with
Proxy-Authenticate/Proxy-Authorization, then you should say that
explicitly near the beginning, and if not, then everywhere you say
"WWW-Authenticate" or "Authorization", you need to allow for the proxy
versions as well. (Maybe just by saying "whenever I say
WWW-Authenticate, I mean 'either WWW-Authenticate or Proxy-Authenticate'.")

I know you said you don't care about typos, but "OWF" should be "OWS".

"rsassa-pkcs1-v1.5-sha-256" is way too long a name. :)

The grammar for method-list says

    method-list     = "method" "=" <"> 1#method-name <">

where "1#method-name" in RFC2616 ABNF means a comma-delimited list of
method-name. But the text (4.2) and the example quoted above use a
space-delimited list. (Likewise with coverage-list.)

The first paragraph of section 5 seems to say that clients MUST include
a Authorization header when requesting a protected resource even if they
don't know that it's protected. :)

In theory, the information in the Authentication-Error response could
just be included in WWW-Authenticate...

If error-message is supposed to be localized then you should allow for
the RFC 2183 grammar (or eventually, the grammar from the RFC that
draft-reschke-rfc2183-in-http becomes).

The "normalized request string" says it includes both the hostname and
the request URI, which would be redundant. Maybe when you say "request
resource URI" you mean just the Request-URI production from the
Request-Line (ie, the path+query), not the actual complete request URI?
You should clarify that. Although if the user is behind a proxy then the
Request-URI will be a complete URI rather than just the path+query. So
you might want to say something like "the path and query components of
the request URI, as they appear in the Request-Line"?

There have been interoperability problems with Digest auth digest
computation because people weren't sure if the quotes around attribute
values were considered part of the value or not when computing the hash.
You should be explicit.

"Any authentication attribute, with the exception of the "auth", which
is assigned a value (including default values), are added to the
normalized request string as follows" is hard to understand. I think
what you mean is "Any attribute which is present in the Authorization
header, with the exception of "auth", is added to the normalized request
string as follows". Hm... although 7.1 seems to suggest something else.
I'm not at all sure what attributes are supposed to be included in the
normalized request string now.

Would probably be good to have an example of computing the string.

-- Dan

---

From: John Panzer <[email-masked]>
Date: Tue, 8 Dec 2009 11:28:44 -0800

(Is there an HTML markup output version available as well?  Easier to link
to...)

"The token scheme support an extensible" --> supports

Suggestion: It would be better to start with simple examples (bearer token)
which avoids the need to wade through concepts like timestamp
synchronization and authentication coverage in order to understand the
simplest possible flow?  (E.g., the example in 1.2.)

Suggestion: Make it clear up front that protected resources are allowed and
encouraged to put a WWW-Authenticate: header on all requests (even ones that
return 200 for read-only access) to indicate what authentication is allowed
in general.  (The equivalent of the "login" link on web pages that present a
read-only view.)

Section 2, step 1:  It sounds like all of the attributes are required even
if some of them are irrelevant to the current credential class.  Suggestion:
attributes that are unnecessary SHOULD be omitted; e.g., method and coverage
are n/a for bearer tokens.  I suppose this is the same as saying that
instead of saying coverage="none" we should omit coverage.

In general, I think that much of the text could be made simpler by
separating out the coverage="none" case from the other cases.  At the moment
the only method under discussion with coverage="none" is bearer token.  I
think that's all there ever will be.  If that's correct, perhaps separating
out things that way would lead to a simpler reading experience (for the
bearer token-users for sure, and possibly for everybody else as they don't
have to worry about the special case of coverage="none" over and over
again.)

Section 5: "A client making a request for a protected resource either
directly,

   or in retrying a request after receiving a 401 status code
   (Unauthorized) with a token challenge, MUST include at least one
   "Authorization" header field including token scheme credentials."

- This could be read as forbidding clients from querying protected resources
before figuring out what Authorization: header to use (as they sometimes
need to make an initial request to discover that the resource is protected).
 Possibly just rewording to "credentialled request"?  What is the right
terminology here?

Section 6: "MAY includes the" --> include the

Section 7: "In addition, the "none" method is

   defined to allow the use of bearer token which does not utilizes any

 cryptographic means."

Grammar: "defined to allow the use of bearer tokens, which do not utilize
cryptographic signatures."
Suggestion:  Calling the token method "none" is odd and jarring.  It makes
me think about the classic routine "Who's on first?".  How about "bearer"?
 As in, the method for request validation is to simply check that it bears
the token.

"relying solely on the
value of the token identifier to authenticate the client"

Surely we are authenticating the request in all these methods?
 (Authenticating the client may be a side effect, but it is neither
necessary nor sufficient.)

Suggestion:  Add a note (SHOULD) about using SSL / TLS when discussing the
bearer token option, either within this section or in the security
considerations section (couldn't find one after some searching).  It's
implied by the discussion in section 8.1 but it's difficult to parse out.

"The "coverage"
attribute MUST be set to "none" but MAY be omitted from the request."

This reads oddly -- I would assume that I can set it to anything if it's
omitted :).  Suggestion:  MUST be either set to "none", or omitted from the
request.

"Nevertheless, these attributes MUST be included in the normalized
 request string together with any other authentication attributes."

After quick read, I have no idea what this sentence means operationally.
 Can you clarify?

--

John Panzer / Google
[email-masked] / abstractioneer.org / @jpanzer

On Mon, Dec 7, 2009 at 12:27 AM, Eran Hammer-Lahav <[email-masked]>wrote:

> scheme to fulfill the WG requirement to produce a scheme suitable for
> 2-legged authentication. It also supports the OAuth 3-legged use cases as
> discussed on the list. This draft is in very early stage and has been
> submitted early to help better facilitate the conversation.
>
> It has been hard for us to discuss ideas without a concrete proposal. I
> hope this will help and motivate people to participate and provide feedback
> and new ideas. While there are many holes in the draft, it should be pretty
> easy to follow it.
>
> Please refrain from editorial feedback at this point (grammar, typos,
> etc.), but do provide structural feedback.
>
> feedback as I can. I plan to ask for the WG to promote this draft to a WG
> item within 2 weeks.
>
> Thanks,
>
> EHL

---

From: Brian Eaton <[email-masked]>
Date: Tue, 8 Dec 2009 22:42:36 -0800

On Mon, Dec 7, 2009 at 11:52 PM, Eran Hammer-Lahav <[email-masked]> wrote:
> Can you list the use cases it doesn't meet? This is largely a cosmetic rewrite of 1.0
> with the exception of directly supporting form-encoded parameters which is still
> being discussed. Your reference is to a post about mostly non-HTTP use cases.

There are basically two use cases for the crypto in OAuth 1.0, and one
major problem.

Major problem: people can't figure out the signature base string.
    The new authentication spec does nothing to fix this, which is a
shame.  It is solvable.

Use case #1: security for people who won't use https.
    We seem to have concluded that this isn't achievable. [1]

Use case #2: security for people who need to send messages through
untrusted third-parties.
    The new authentication spec makes this much, much harder.

Here are a few examples of places where people are using OAuth to send
messages through untrusted third-parties.  Every single one of these
use cases is broken by the token-auth spec [2].  If we can't solve
these problems, there is very little point in message authentication
at all.

For example:
- signed URLs embedded in the browser [3]
- opensocial identity parameters [4]
- google-specific identity parameters [5]
- intermediate xmpp servers [6]
- intermediate sip servers [6]

We should be trying to make those use cases *easier*, not make them
impossible.  If we push a new OAuth spec that drops these use cases,
we've done more harm than good.

Cheers,
Brian

[1] http://www.ietf.org/mail-archive/web/oauth/current/msg00762.html
[2] http://www.ietf.org/id/draft-hammer-http-token-auth-00.txt
[3] http://www.ietf.org/mail-archive/web/oauth/current/msg00689.html
[4] http://www.opensocial.org/Technical-Resources/opensocial-spec-v09/Gadgets-API-Specification.html#gadgets.io.makeRequest
[5] http://code.google.com/apis/accounts/docs/OAuth.html#GoogleAppsOAuth
[6] http://www.ietf.org/mail-archive/web/oauth/current/msg00513.html