Subject: Web Keys and HTTP Signatures

From: Manu Sporny <[email-masked]>
Date: Wed, 17 Apr 2013 17:32:17 -0400

We've implemented Joyent's (node.js) HTTP Signature specification using
the public key infrastructure defined by the PaySwarm Web Keys spec.
We're pretty happy with the solution given that this is the third
approach that we've tried to apply to the HTTP request signatures problem.

For those not familiar with Joyent's HTTP Signature specification, it's
here:

https://github.com/joyent/node-http-signature/blob/master/http_signing.md

The Web Keys (horribly outdated) spec is here:
https://payswarm.com/specs/source/web-keys/

The modification that has been made to Joyent's spec is to:

1. Use a Web Key URL for the keyId parameter, which changes Joyent's
   solution to depend on a Web-native, decentralized public key
   infrastructure.
2. Sign the request line, date, and host parameters by default to
   tighten up the default security requirements (to reduce, but not
   eliminate, replay attacks).

What this means is that you can now do signed HTTP requests like GETs on
specific resources in a fairly simple and decentralized way. It also
means that you can use the Web Key information to create an Access
Control List to HTTP-based resources and enforce both authentication and
authorization of GETs/POSTs/etc. in one HTTP call.

This feature has already been integrated into the request HTTP module in
node.js:

https://github.com/mikeal/request/commit/95a25580375be1b9c39cc2e88a36a8387395bc13

We'll be releasing a few demos of how one can use this authorization
scheme with Web Keys in the next couple of weeks. We expect to integrate
these sorts of HTTP Signatures into the Web Keys specification.

-- manu

-- 
Manu Sporny (skype: msporny, twitter: manusporny, G+: +Manu Sporny)
Founder/CEO - Digital Bazaar, Inc.
blog: Meritora - Web payments commercial launch
http://blog.meritora.com/launch/

---

From: Carsten Bormann <[email-masked]>
Date: Thu, 18 Apr 2013 00:03:14 +0200

> https://github.com/joyent/node-http-signature/blob/master/http_signing.md

I looked at this for about 5 seconds, but are you telling us the attacker gets to choose what the lines in the signed string are supposed to mean?

Grüße, Carsten

---

From: "David I. Lehn" <[email-masked]>
Date: Wed, 17 Apr 2013 19:13:24 -0400

> I looked at this for about 5 seconds, but are you telling us the attacker gets to choose what the lines in the signed string are supposed to mean?

I'm not sure I understand your question? The request signature
specifies the headers that are signed. The server can reject a request
based on a header requirement policy. Our current implementation
requires the headers to at least include request-line, host, and date.
What specific attack did you have in mind?

-dave

---

From: "Manger, James H" <[email-masked]>
Date: Thu, 18 Apr 2013 09:56:01 +1000

Bad guy swaps the values of two headers (hence changing the semantics of the HTTP request). Bad guy also swaps the order in which the two headers are listed in the 'headers' attribute (hence the signing string is the same). Consequence: same signature is valid for two different requests.

A bad guy cannot change the signing string but, as Carsten notes, they can change which line of the signing string is treated as the date, as the content-type, as whatever by adjusting the unprotected 'headers' attribute.

P.S. This scheme doesn't match the allowed syntax for the Authorization header. After "Signature" you can have a single base64 blob OR comma-separated name=value pairs -- you cannot mix the two. Stick sig="..." around the signature.

--
James Manger

> -----Original Message-----
> From: [email-masked] [mailto:[email-masked]] On Behalf Of David I.
> Lehn
> Sent: Thursday, 18 April 2013 9:13 AM
> To: Carsten Bormann
> Cc: Manu Sporny; Web Payments CG; [email-masked]
> Subject: Re: Web Keys and HTTP Signatures
> 
> >> https://github.com/joyent/node-http-
> signature/blob/master/http_signin
> >> g.md
> >
> > I looked at this for about 5 seconds, but are you telling us the
> attacker gets to choose what the lines in the signed string are
> supposed to mean?
> >
>

---

From: Martin Thomson <[email-masked]>
Date: Wed, 17 Apr 2013 17:00:20 -0700

Yeah, that's a pretty bad.  Switching two date-formatted headers might
be a simple thing to gain advantage on.  (Last-Modified and Date,
might work to poison a cache with old content if the cache isn't
rigorous about checking Date).  It seems like a simple fix would be to
include the list of headers under the signature as the first item.

---

From: "David I. Lehn" <[email-masked]>
Date: Wed, 17 Apr 2013 20:22:40 -0400

On Wed, Apr 17, 2013 at 5:32 PM, Manu Sporny <[email-masked]> wrote:
> ...

This is a work in progress but is live on our sandbox server
https://dev.payswarm.com/.  I don't want to keep everyone in suspense,
so here's a quick developer view on how to try this right now. :-)

Grab the latest payswarm.js from git and "npm install" the
dependencies. If you had a previous checkout, make sure jsonld is
up-to-date and has the latest require module from git.
https://github.com/digitalbazaar/payswarm.js

Create an account on https://dev.payswarm.com/ if you don't already have one.

If you don't already have an access key, run the following and follow
the instructions to register one:
node ./examples/register-new-key.js

You should have a "payswarm.cfg" file that has your key info.

Now you can use a raw curl-like tool we just wrote to access resources
on the PaySwarm Authority:
./bin/payswarm url https://dev.payswarm.com/i/myid/accounts

If you want to see the signature it's sending, you can use the debug
mode and look for the "REQUEST httpSignature authorization" line.
NODE_DEBUG=request ./bin/payswarm url https://dev.payswarm.com/i/myid/accounts

The app is passing a list of headers we require along with the key id
and private key PEM from the config file down through to the recently
added HTTP signature support in the request module. The request gets
signed and shipped off and the server verifies it based on the public
key that was registered for that id. Then the request is then,
roughly, authorized the same as a session on the website.

This code just came online yesterday and really is a work in progress.
We're working to improve the tools and flow but you can use it now.
Please let us know how it works, if you have problems, or if you find
security issues. Thanks!

-dave

---

From: Carsten Bormann <[email-masked]>
Date: Thu, 18 Apr 2013 07:54:11 +0200

On Apr 18, 2013, at 02:22, "David I. Lehn" <[email-masked]> wrote:

> if you find security issues

Wrong question.

A security spec is worthless if it doesn't establish useful security properties.

The spec needs a good look from people with more security mojo.
(Or maybe it can simply be replaced by one of the more learned attempts under discussion, see
http://www.ietf.org/proceedings/85/minutes/minutes-85-httpauth
http://www.ietf.org/proceedings/86/minutes/minutes-86-httpauth
for some links.)

*Then* you can look at whether you have implemented it correctly.

Grüße, Carsten

---

From: Carsten Bormann <[email-masked]>
Date: Thu, 18 Apr 2013 10:11:18 +0200

On Apr 18, 2013, at 02:00, Martin Thomson <[email-masked]> wrote:

> It seems like a simple fix would be to

Obviously.

The reason I didn't give this fix is that this just amounts to handing out more rope.

It seems to me the community may not have the resources to come up with a secure spec on their own.
I'd rather motivate them to spend some quality time with security experts than just throw "fixes"  for the immediately obvious problems over the wall, somehow hoping nobody will find the deeper ones.

Grüße, Carsten

---

From: Manu Sporny <[email-masked]>
Date: Thu, 18 Apr 2013 09:42:11 -0400

On 04/17/2013 08:00 PM, Martin Thomson wrote:
> Yeah, that's a pretty bad.  Switching two date-formatted headers 
> might be a simple thing to gain advantage on.  (Last-Modified and 
> Date, might work to poison a cache with old content if the cache 
> isn't rigorous about checking Date).  It seems like a simple fix 
> would be to include the list of headers under the signature as the 
> first item.

Carsten, James, Martin - good catch, thanks. We had assumed that the
implementation included the headers names as well as the values in the
data being digitally signed. As Dave Lehn pointed out, this is a work in
progress, but we wanted to get something out as sooner than later.

The attack is only possible if a message is passed over a non-secure
channel, right? That is, the spec is clear about passing all messages
over HTTPS. Granted, that's not an excuse for the approach taken and it
should be fixed, but the attack is only possible if messages are sent
over an insecure channel, correct?

-- manu

---

From: Amos Jeffries <[email-masked]>
Date: Fri, 19 Apr 2013 01:55:41 +1200

> over an insecure channel, correct?

We had this argument out in the Bearer auth discussions. HTTPS is just 
one layer of security, it can (and routinely is) broken into by 
transparent proxies.

Your auth scheme needs to be as self-contained as possible and take 
advantage of every little bit of security that it can do without relying 
on external layers such as the SSL/TLS layer. It is better to be 
doubly-strong when HTTPS works than to depend on it alone break at the 
first sign of trouble.

IMO signed message schemes like this stand a far better chance of being 
rolled out if they work on plain-HTTP. There are a number of web 
applications and service which require security without the sledgehammer 
and limitations of TLS.

Amos

---

From: Daniel Friesen <[email-masked]>
Date: Thu, 18 Apr 2013 07:01:48 -0700

> over an insecure channel, correct?
You might want to think twice before you consider https implemented in
anything other than a web browser absolutely secure:
http://hueniverse.com/2010/09/oauth-bearer-tokens-are-a-terrible-idea/

~Daniel Friesen (Dantman, Nadir-Seen-Fire) [http://danielfriesen.name/]

---

From: Stephen Farrell <[email-masked]>
Date: Thu, 18 Apr 2013 15:01:56 +0100

> applications and service which require security without the sledgehammer

And in the "other relevant work" thread, aside from httpauth
(where I'm a co-author on a similar-ish proposal [1] and be
happy to chat about it, maybe the http-auth list is better
though), there's also work to use DKIM-like headers for
iSchedule [2]. I've not read this though (yet) to see if
they're all really that different or not.

Cheers,
S.

[1] http://tools.ietf.org/html/draft-farrell-httpbis-hoba
[2] http://tools.ietf.org/html/draft-desruisseaux-ischedule

---

From: David Morris <[email-masked]>
Date: Thu, 18 Apr 2013 07:32:08 -0700 (PDT)

On Thu, 18 Apr 2013, Carsten Bormann wrote:

> I'd rather motivate them to spend some quality time with security
> experts than just throw "fixes"  for the immediately obvious problems
> over the wall, somehow hoping nobody will find the deeper ones.

I agree with you on the use of expertise. But to belabor the obvious,
including the header list in the signature doesn't change any reorder
property. If the header values can be swapped without the list included,
they can still be reordered with the list included. 

I've not read the design, but I don't understand how any modern 
signature hash wouldn't require a deterministic order for the header
values in the signature. That would seem to preclude a simple
swapping of values.

---

From: Carsten Bormann <[email-masked]>
Date: Thu, 18 Apr 2013 17:04:21 +0200

> But to belabor the obvious,

In the design I was criticizing, a sequence of values was signed, but the mapping from the position in the list of values to a specific header field was in an unprotected field.  So Alice could send a Content-MD5 header, and Charlie could not change its value, but change the meaning of the header to a mumble-foo header, and Bob would be none-the-wiser.
(Of course, the use of Content-MD5 in the spec is the next problem.  And so on.
If Stephen looks at this, I'm happy.)

Grüße, Carsten

---

From: Ken Murchison <[email-masked]>
Date: Thu, 18 Apr 2013 11:48:46 -0400

> [2] http://tools.ietf.org/html/draft-desruisseaux-ischedule

I was also going to suggest folks look at iSchedule, which leverages the 
already proven/scrutinized DKIM technology for signing its HTTP 
requests.  That draft is only concerned about iSchedule and not general 
purpose HTTP requests, but a similar methodology could be used.

A few things to note:

  * Earlier versions of the draft signed both the request-line and Host
    header, but we found in interop testing that intermediaries might
    alter the request-target and/or Host, thus breaking the signature. 
    We punted on both because 1) all iSchedule requests are sent to one
    request target (there is only a single "resource" on an iSchedule
    receiver) therefore the receiver can determine if the request-target
    is valid, and 2) the receiver can deduce from the signed Recipient
    header(s) if it was the intended Host.  My guess is that both of
    these issues would have to be addressed if a DKIM-like method was
    going to be applied to general HTTP requests.  Use of the Forwarded
    header [3] might help in addressing these issues, but I haven't
    thought much about it.
  * Earlier versions of the draft used the standard DKIM "relaxed"
    header canonicalization algorithm, but we found in interop testing
    that intermediaries and/or HTTP libraries might combine multiple
    headers of the same name (#list-type header) into a single header,
    thus breaking the signature.  As a result, we had to define our own
    "ischedule-relaxed" header canonicalization algorithm which
    essentially combines such headers before signing/verifying.
  * iSchedule is only concerned with signing requests at a domain level,
    not on an individual user level.  A new DKIM key query method might
    be able to be designed to handle fetching of user keys.

[3] http://tools.ietf.org/html/draft-ietf-appsawg-http-forwarded

-- 
Kenneth Murchison
Principal Systems Software Engineer
Carnegie Mellon University

---

From: Manu Sporny <[email-masked]>
Date: Thu, 18 Apr 2013 12:19:44 -0400

> A security spec is worthless if it doesn't establish useful security

Correct. I think Dave Lehn was making a general statement "If you find
more issues, please let us know.", he was not asking a question. I
believe that you are talking past what he was saying.

You also seem to be implying that you know of which security properties
are not being established by http-signatures. Could you please elaborate?

> The spec needs a good look from people with more security mojo.

We agree, which is why we published an implementation, pointed to the
spec, and cc'd the IETF HTTP WG. A very positive thing has come out of
that, which is that an issue was found with the spec and implementation.

> http://www.ietf.org/proceedings/86/minutes/minutes-86-httpauth for 
> some links.)

Thanks for the link. We've looked at a number of those before, or
variants of the approaches. Here's feedback on each:

HTTP Origin-Bound Authentication (HOBA)
http://tools.ietf.org/id/draft-farrell-httpbis-hoba-02.txt

We had considered signatures in the URL in the second approach to the
problem in the Web Keys spec. We eventually rejected the solution
because of limitations in the URL length in some browsers and because we
wanted the semantics of the HTTP headers to be able to be a part of the
digital signature. We also didn't want large signed messages being
dumped to the webserver logs (the request line is typically included).
So, while HOBA does solve the problem, it doesn't solve it in a way that
is acceptable to us.

HTTP Mutual Authentication
http://tools.ietf.org/html/draft-oiwa-http-mutualauth-12

Overkill for our purposes and requires multiple bounces back and forth
between the client and the server. Key exchange isn't required since
that's taken care of by the Web Keys PKI framework. We don't intend the
Web Keys HTTP signature protocol to be session-based, as a session-based
value can be built on top of HTTP signatures pretty easily.

HTTP Multilegged Auth
http://tools.ietf.org/id/draft-montenegro-httpbis-multilegged-auth-01.txt

Seems like overkill for our needs and is fairly specific to HTTP 2.0. We
wanted something that could work for HTTP 1.0. Multi-legged
authentication is something that we're not interested in solving using
HTTP Signatures. Putting state into the protocol is something we'd like
to avoid if possible.

HTTP Salted Challenge Response
http://tools.ietf.org/html/draft-melnikov-httpbis-scram-auth-00

Uses HMACs, doesn't use public key crypto, which is a requirement for
Web Keys and the Web Payments work.

HTTP REST Auth
http://tools.ietf.org/id/draft-williams-http-rest-auth-03.txt

This was the solution that seemed to be most interesting to the Web Keys
and Web Payments work. However, it requires quite a bit of state to be
remembered by the server (the Session URIs). Keeping the state of a
"session" around isn't desirable. We didn't want there to be a concept
of logging in and logging out of a website w/ the HTTP Signature stuff.
We'd rather that sessions are built on top of HTTP Signatures via a HTTP
header or cookie. Again, if we had to pick a back-up solution, HTTP REST
Auth seems like it might work for us, but we'd rather not use if we
don't have to.

Hopefully this explains why we haven't picked any of the solutions that
you outlined in your response. Web Keys + HTTP Signatures are simpler,
and we're now in the discovery phase to see if the protocol will stand
up to scrutiny by the security community.

-- manu

---

From: Carsten Bormann <[email-masked]>
Date: Thu, 18 Apr 2013 18:39:37 +0200

> are not being established by http-signatures. Could you please elaborate?

No, I just reported that I got stuck trying to find out the security properties.

I was also unclear about the security objectives.  This is starting to become a bit clearer with the discussion now, but that doesn't replace a good exposition of what you are trying to achieve/what you think you have achieved.  So, for instance, I'd like to understand your stance on replay a bit better.  RFC 3552 and RFC 4101 may be good reading for the kind of question that tends to come up, and RFC 4949 will give you some terminology to minimize ambiguity.

Thanks a lot for the appraisal of the httpauth candidates -- this will be really useful input for the work of that WG.

Grüße, Carsten

---

From: Manu Sporny <[email-masked]>
Date: Thu, 18 Apr 2013 13:23:56 -0400

On 04/18/2013 04:11 AM, Carsten Bormann wrote:
>> It seems like a simple fix would be to include the list of headers
>> under the signature as the first item.
> 
> Obviously.
> 
> It seems to me the community may not have the resources to come up
> with a secure spec on their own. I'd rather motivate them to spend
> some quality time with security experts than just throw "fixes"  for
> the immediately obvious problems over the wall, somehow hoping nobody
> will find the deeper ones.

Carsten, this particular response is not helpful because:

1. You seem to be claiming to have knowledge about the proposed fix that
   makes it seem like the solution is a dead-end, yet you don't
   elaborate upon the claim.
2. You seem to be insinuating that there are deeper problems with the
   HTTP Signatures approach without expanding upon what those may be.
3. You make an appeal to authority (re: the "security experts" will be
   able to help.) without knowing who wrote the specifications,
   who is reading this thread and commenting elsewhere, nor who has
   already reviewed the specifications.

The reason we sent the initial message out was because we wanted
feedback from various communities, including the "security experts"
whoever those people may be. Responses like the one you make above don't
actually help us identify issues in the protocol or approach that are
being taken. I know that you probably did not mean to come across as
condescending or patronizing, but you have.

I'd like us to focus on technical issues and helping each other rather
than the sort of exchange above.

-- manu

---

From: Manu Sporny <[email-masked]>
Date: Thu, 18 Apr 2013 13:54:04 -0400

> http://hueniverse.com/2010/09/oauth-bearer-tokens-are-a-terrible-idea/

Yeah, good piece by Eran, seen it.

In the most basic form of Web Payments, we require HTTPS and HTTP
Signatures. For operations that are very sensitive, we require HTTPS,
HTTP Signatures, and digitally signed JSON.

> doubly-strong when HTTPS works than to depend on it alone break at the 

See above. We have multiple layers where it's important so hopefully if
one layer fails, the other two will make up for it to prevent a compromise.

-- manu

---

From: Manu Sporny <[email-masked]>
Date: Thu, 18 Apr 2013 14:34:50 -0400

> No, I just reported that I got stuck trying to find out the security

Ok, that wasn't clear. More on this below...

> I was also unclear about the security objectives.  This is starting 
> to become a bit clearer with the discussion now, but that doesn't 
> replace a good exposition of what you are trying to achieve/what you
>  think you have achieved.

This might help with respect to the Web Keys specification:

https://hacks.mozilla.org/2013/04/web-payments-with-payswarm-identity-part-1-of-3/

This might help with respect to the Web Payments work:

> So, for instance, I'd like to understand your stance on replay a bit 
> better.

Short story: Replay is bad, we try to prevent it. :)

We have two protections against replay attacks in Web Key digital
signatures. The first is a nonce, which is optional under certain
circumstances. The second is a datetime stamp which is used to
time-block an attack period (for example - 5 minutes).

We made nonces optional as not everyone will require them. The Web
Payments specs require nonces to be implemented correctly as an
additional security measure. We also require payment processors to
always use HTTPS as a further security measure.

The documentation is pretty dated on this stuff, but you can read more
about it here:

https://payswarm.com/specs/source/web-keys/#the-response-token

and here:

https://payswarm.com/specs/source/web-keys/#message-signature-algorithm

> RFC 3552 and RFC 4101 may be good reading for the kind of question 
> that tends to come up, and RFC 4949 will give you some terminology
> to minimize ambiguity.

Yep, we're working on explanations about the design behind web keys.
Unfortunately, the spec is quite out of date. Implementations match the
current design, but we need to move what we do in the implementations
back into the Web Keys spec.

Keep in mind that the HTTP Signatures spec intended to be a sub-section
of Web Keys. We could publish it separately if that would move it toward
REC (at W3C) or RFC (at IETF) faster.

> Thanks a lot for the appraisal of the httpauth candidates -- this 
> will be really useful input for the work of that WG.

I'll send another e-mail to that mailing list to make sure that we're
engaging the right community. I'll stop cc'ing the HTTP WG shortly,
unless the conversation should continue in this group as well?

-- manu