Subject: [OAUTH-WG] Use Cases for Signed Tokens

From: Justin Richer <[email-masked]>
Date: Thu, 3 Jan 2013 17:45:10 -0500

I'd like to present two use cases for signed tokens, for input into the 
ongoing MAC/HoK/higher-security discussion. Both of these are actual 
cases that I've done in the past, and we've used either OAuth 1 or JW* 
to solve them. I think that with the right tooling, a MAC-token-like 
thing could be used here. I'll note to the crypto nerds in the group 
(ahem, John) that I'm going to be using terms like "signing" and "MAC" 
in a somewhat loose sense, so please don't get hung up on that because I 
think you actually know what I mean.

So:

1) Message-level signing.

In this, you protect the content of the HTTP message by signing it with 
the secret part of the token, effectively what was done in OpenID 2, 
OAuth1, and the MAC draft. You pick some subset of the HTTP components, 
add them to your signing base in a predictable and repeatable fashion, 
and sign it with your secret. You then send the signature along with all 
of the bare HTTP elements across the wire, and the far side does the 
same signature generation magic and you're good to go.

The driving use case to this is security in depth. Yes, you probably 
still do want everything to go over TLS, but that only protects things 
in transit between endpoints. It won't protect anything as it gets 
chewed through an application platform or handed around a server farm. 
It's also considered "best practice" in many cases. In my experience in 
the health care space, you almost always want to have multiple layers 
protecting you.

An alternative approach here is to use a JW* container like a JWS or JWE 
to hold all of your parameters (as claims) and sign/encrypt over that. 
But if you do that, you're not really using HTTP anymore, except as a 
dumb transport. This is the approach of SOAP, and I doubt that many will 
come to its defense. (At least, those that don't want to sell you 
something to process SOAP messages.) We've done this ourselves with a 
prototype, and losing all of the processing capability that comes with 
HTTP is a huge programmatic hit.

2) Signed URL as an authorized artifact.

In this, you have party A generate a URL with parameters in it, 
protected by a signature. That URL points to party B, who can validate 
the signature. Party A then hands that fully baked URL to a third party, 
C, who can't do anything to the parameters in the URL without messing up 
the signature. From party B's perspective, so long as that signature is 
valid, all the parameters in the URL can be trusted and the request can 
proceed. With a timestamp and nonce parameter (built in to OAuth1), 
you've even got really nice replay and timeout protection. TLS doesn't 
do you any good here, because there's a party in the middle who has the 
full right to hold and view the artifact (URL), but does not have the 
right to modify it. We've solved this in the past using OAuth1's 
signature mechanism without tokens (aka, 2-legged OAuth1). We can't 
currently do this with OAuth2. If we had a generalizable HTTP components 
signing mechanism (which MAC *almost* is, and could become), then we could.

Again, you could simply cram everything into a JW* container and send 
*that* as the sole parameter to a URL and get almost the same result. 
But then you've got to unpack that JW* container to get all of your 
parameters, and you're back in SOAP land. And again I posit: nerds hate 
SOAP.

Hopefully both of these will help inform the discussion and shed some 
light onto why I think that:
  * MAC tokens (or equivalent) are still a good idea for the WG to pursue
  * Channel-binding and TLS don't solve all security problems
  * Abusing JOSE leads to breaking good HTTP designs

  -- Justin

---

From: Hannes Tschofenig <[email-masked]>
Date: Fri, 11 Jan 2013 11:33:24 +0200

Hi Justin,

thanks for the input. 

A few minor remarks inside: 

On Jan 4, 2013, at 12:45 AM, Justin Richer wrote:

> I'd like to present two use cases for signed tokens, for input into the ongoing MAC/HoK/higher-security discussion. Both of these are actual cases that I've done in the past, and we've used either OAuth 1 or JW* to solve them. I think that with the right tooling, a MAC-token-like thing could be used here. I'll note to the crypto nerds in the group (ahem, John) that I'm going to be using terms like "signing" and "MAC" in a somewhat loose sense, so please don't get hung up on that because I think you actually know what I mean.
> 
> So:
> 
> In this, you protect the content of the HTTP message by signing it with the secret part of the token, effectively what was done in OpenID 2, OAuth1, and the MAC draft. You pick some subset of the HTTP components, add them to your signing base in a predictable and repeatable fashion, and sign it with your secret. You then send the signature along with all of the bare HTTP elements across the wire, and the far side does the same signature generation magic and you're good to go.
> 
> The driving use case to this is security in depth. Yes, you probably still do want everything to go over TLS, but that only protects things in transit between endpoints. It won't protect anything as it gets chewed through an application platform or handed around a server farm. It's also considered "best practice" in many cases. In my experience in the health care space, you almost always want to have multiple layers protecting you.
> 
> An alternative approach here is to use a JW* container like a JWS or JWE to hold all of your parameters (as claims) and sign/encrypt over that. But if you do that, you're not really using HTTP anymore, except as a dumb transport. This is the approach of SOAP, and I doubt that many will come to its defense. (At least, those that don't want to sell you something to process SOAP messages.) We've done this ourselves with a prototype, and losing all of the processing capability that comes with HTTP is a huge programmatic hit.

I understand the value of the message level protection vs. the usage of TLS. If you go to the extreme then you could argue that HTTP is terminated in the HTTP stack and not at the application... This line of argumentation wouldn't be too crazy given that some of the HTTP parameters are not accessible through certain application development platforms, for example. 

If you abstract a bit then the two approaches are not so different. Here is the story:

* With an HTTP-based solution you do
   - put additional parameters into the header to convey the algorithm related information, the access token, and the keyed message digest
   - the keyed message digested is computed over some HTTP headers and it would be possible to repeat the value that is used as input to the keyed message digest computation in another parameter.

* With a JSON-based solution you do
   - put the access token and the encoded JSON structure into a header (or alternatively into the body)
   - the signature or keyed message digest is computed over the JSON structure which includes information that relates to the HTTP request. Again, whether you repeat the values in the JSON itself or only a hash of them has not yet been decided. During the OAuth 1.0 days some folks argued that the values should be repeated so that one can easily detect problems. 

Do you see the similarity (expect for the encoding of the parameters)?

> In this, you have party A generate a URL with parameters in it, protected by a signature. That URL points to party B, who can validate the signature. Party A then hands that fully baked URL to a third party, C, who can't do anything to the parameters in the URL without messing up the signature. From party B's perspective, so long as that signature is valid, all the parameters in the URL can be trusted and the request can proceed. With a timestamp and nonce parameter (built in to OAuth1), you've even got really nice replay and timeout protection. TLS doesn't do you any good here, because there's a party in the middle who has the full right to hold and view the artifact (URL), but does not have the right to modify it. We've solved this in the past using OAuth1's signature mechanism without tokens (aka, 2-legged OAuth1). We can't currently do this with OAuth2. If we had a generalizable HTTP components signing mechanism (which MAC *almost* is, and could become), then we could.
> 
> Again, you could simply cram everything into a JW* container and send *that* as the sole parameter to a URL and get almost the same result. But then you've got to unpack that JW* container to get all of your parameters, and you're back in SOAP land. And again I posit: nerds hate SOAP.

Let me see whether I get that idea right. In this case you put the OAuth related parameter, access token, and keyed message digest into the URL instead of putting it into the HTTP header (as a parameter). Is this the main difference? If so, why do you care whether the values are carried in the header vs. in the URL? 

A slightly separate question: Out of curiosity, what specifically do you dislike about SOAP (even though it has little relationship to what we do here)? Is it the verbose nature due to the usage of XML? Is it the header that contains values that you may not need? Is it WSDL that most people use with SOAP?

> Hopefully both of these will help inform the discussion and shed some light onto why I think that:

TLS and channel bindings can provide additional security features for an application layer solution. 
The channel binding ensures that the TLS exchange is not terminated at an intermediary. 

So, it might be useful to also see them as additional layer of defense rather than as a competitor.  

> * Abusing JOSE leads to breaking good HTTP designs

I understand the philosophical argument but not necessarily the "breaks good HTTP design". You can still use HTTP in the way you want. How are you constrained when you use a JSON encoding as compared to a custom encoding? 

Ciao
Hannes

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

---

From: "Richer, Justin P." <[email-masked]>
Date: Fri, 11 Jan 2013 14:34:46 +0000

Hannes, thanks for the input. Inline:

On Jan 11, 2013, at 4:33 AM, Hannes Tschofenig <[email-masked]>
 wrote:

> I understand the value of the message level protection vs. the usage of TLS.

Just a note that it's not necessarily "vs." in the use case, it's "in addition to". Multiple layers of security are considered best practice in many cases, not the least of which is healthcare. Even if you have something set up with mutual TLS, you're supposed to protect each message separately as well. 

> If you go to the extreme then you could argue that HTTP is terminated in the HTTP stack and not at the application... This line of argumentation wouldn't be too crazy given that some of the HTTP parameters are not accessible through certain application development platforms, for example. 
> 

I do see the similarity, but the encoding of the parameters is exactly the difference that I think is important to the argument I'm making above. I could also encode all of my parameters as an ASN.1 document, or XML, or whatever, and I'd be in roughly the same boat.

> Let me see whether I get that idea right. In this case you put the OAuth related parameter, access token, and keyed message digest into the URL instead of putting it into the HTTP header (as a para…

Yes that's correct - In this use case, everything goes in the URL. If everything goes in the URL, then you've got a single artifact that you can pass around to different systems. You can't do that with HTTP headers, which makes it an untenable approach for this.

> A slightly separate question: Out of curiosity, what specifically do you dislike about SOAP (even though it has little relationship to what we do here)? Is it the verbose nature due to the usage of…

I think you're getting hung up on the specifics of the SOAP protocol set (XML, WSDL) and missing my main point: SOAP doesn't make use of HTTP in the best way it can. 
 - ignores all aspects of HTTP like action verbs, headers, and query parameters in favor of putting everything in a specialty-encoded document
 - can't be used without complex tooling (smoke test: can I script this API with wget?)
 - complex tools from different vendors don't tend to be very interoperable with each other without significant engineering of the application

> So, it might be useful to also see them as additional layer of defense rather than as a competitor.  

Again it's not a "one or the other" thing here. I was simply trying to make the point that TLS channel binding, while useful at solving its own set of issues, is not a panacea. Neither of these two use cases, for example, can be addressed by it at all. If you do have TLS *on top of* these other approaches, yes, that can make it even better. And it's exactly that independent modularity that makes this stuff worthwhile, in my opinion.

> I understand the philosophical argument but not necessarily the "breaks good HTTP design". You can still use HTTP in the way you want. How are you constrained when you use a JSON encoding as compar…

If you cram all of your verbs and parameters into a JOSE-encoded body, you're not using HTTP in what is today considered best practice. This philosophy, again, was a main failing of SOAP and what made it ultimately fail in the market.

 -- Justin

---

From: Hannes Tschofenig <[email-masked]>
Date: Fri, 11 Jan 2013 18:57:27 +0200

Hi Justin, 

see below. 

> Just a note that it's not necessarily "vs." in the use case, it's "in addition to". Multiple layers of security are considered best practice in many cases, not the least of which is healthcare. Eve…

I guess we agree on that aspect. 

> I do see the similarity, but the encoding of the parameters is exactly the difference that I think is important to the argument I'm making above. I could also encode all of my parameters as an ASN.…

Good that you see the similarity. I understand that you have a preference regarding the encoding. 

> Yes that's correct - In this use case, everything goes in the URL. If everything goes in the URL, then you've got a single artifact that you can pass around to different systems.
> You can't do that with HTTP headers, which makes it an untenable approach for this.

Regarding "passing it around to different systems". Based on the security you can only use this URL once between the client and the resource server (for a single request).

> - complex tools from different vendors don't tend to be very interoperable with each other without significant engineering of the application

You started referring to SOAP and I was therefore wondering what exactly the relationship to this discussion is. 

In our case where in the discussion between MAC and a JSON-based encoding we 
 - have no difference regarding HTTP aspects
 - the encoding always has to be defined (regardless of whether it is JSON-based or a custom defined encoding as with MAC)
 - always requires some "complex tooling" since you cannot expect a human to calculate a keyed message digest (at least I cannot) or a digital signature
 - the interoperability comes from the specification: if everything is correctly specified than two software packages from independent vendors are able to compute the same keyed message digest (or digital signature) when given the same input.   

> Again it's not a "one or the other" thing here. I was simply trying to make the point that TLS channel binding, while useful at solving its own set of issues, is not a panacea.

I don't think anyone said that TLS, and channel binding solve all security problems. They solve the problems they are designed for. 

> Neither of these two use cases, for example, can be addressed by it at all.

I never said claimed they do. 

> If you do have TLS *on top of* these other approaches, yes, that can make it even better.
Agree. 

> And it's exactly that independent modularity that makes this stuff worthwhile, in my opinion.
Ack. 

> If you cram all of your verbs and parameters into a JOSE-encoded body, you're not using HTTP in what is today considered best practice. This philosophy, again, was a main failing of SOAP and what m…
You don't need to copy the HTTP parameters that serve as input to the keyed message digest into the JSON payload, if you don't want. 
There are various design choices. For example, with both approaches you could, for example, list the header fields in the order they are put into the signature string. This design is, for example, chosen by DKIM (see http://tools.ietf.org/html/rfc4871#appendix-A.2). 

In case you don't to include the signature string explicitly in the message then the difference between the two approaches is: 
(Note that I did not include the access token in the examples below.)

MAC:

Authorization: MAC id="h480djs93hd8",
                        ts="1336363200",
                        nonce="dj83hs9s",
                        mac="bhCQXTVyfj5cmA9uKkPFx1zeOXM="

JSON:

Authorization: MAC2 value="asdflkjasdf;lkadsdfkjskjsdfkjdsfjsfkadsfj.dBjftJeZ4CVP-mB92K27."

(this value is supposed to indicate a header followed by a keyed message digest. The header, for example, could be something like: 

{"typ":"HOTK-SK",
       "alg":"HS256",
       "kid":"[email-masked]",
       "timestamp":"2012-07-15T10:20:00.000-05:00" }
 
Ciao
Hannes

---

From: Sergey Beryozkin <[email-masked]>
Date: Sun, 20 Jan 2013 21:28:06 +0000

Hi,
> * Abusing JOSE leads to breaking good HTTP designs

IMHO it's a very good summary - and a good read.
While this is off-topic, it might also make sense to consider MAC as a 
light weight alternative to JW*, with both token styles nicely 
complementing each other and covering the signed tokens space 
completely, as opposed to prioritizing on a single token only which IMHO 
may not be ideal, which is also highlighted above by Justin

Thanks, Sergey