w3c / payment-request

Payment Request API
https://www.w3.org/TR/payment-request/
Other
488 stars 135 forks source link

Applying "Detached" JWS Signatures to PaymentRequest #714

Closed cyberphone closed 6 years ago

cyberphone commented 6 years ago

Assume you have PaymentRequest object like the following:

{
  supportedMethods: "https://example.com/bobpay",
  data: {
     merchantIdentifier: "XXXX",
     bobPaySpecificField: true
  }
}

If such data needs to be signed, there is currently no standardized method for signing JSON data except through Base64Url-encoding the entire object which is in conflict with the API concept.

It would be cool adding an element containing a detached JWS signature like this:

{
  supportedMethods: "https://example.com/bobpay",
  data: {
     merchantIdentifier: "XXXX",
     bobPaySpecificField: true,
     signature: "eyJ0eXAiOiJKV1QiLA0KIC.S9pc19yb290Ijp0cnVlfQ.VP-mB92K1p1r_wWWFOEjXk"
  }
}

Unfortunately that doesn't really work because the order of JSON properties is undefined.

However, a recently published (draft) specification can be used as a bridge between detached JWS and clear text JSON/JavaScript data:

  1. Apply https://tools.ietf.org/html/draft-rundgren-json-canonicalization-scheme-00 to a JSON-serialized version of the object to be signed
  2. Apply https://tools.ietf.org/html/rfc7515#appendix-F to the result of the above operation
  3. Add the resulting compact JWS to the original object through a new property like the sample's signature

https://github.com/cyberphone/json-canonicalization#json-canonicalization

marcoscaceres commented 6 years ago

Unfortunately that doesn't really work because the order of JSON properties is undefined.

All browsers respect order of properties. Authors depend heavily on having the order of those properties be in order and it would be "web breaking" to consider them as unordered.

marcoscaceres commented 6 years ago

To be clear, if the bug is "order of JSON properties is undefined", and given that there is agreement in browsers that order is actually respected, then the ECMAScript spec should be updated, but doesn't affect Payment Request (which is why I'm closing this issue).

cyberphone commented 6 years ago

@marcoscaceres I think you were a bit hot on the trigger here šŸ˜‚. The Creator of the signature would not be a browser and is thus affected by JSON property (un)order.

Imagine a PaymentHandler scenario. The browser can't do much with the signature since the key used to sign with, hardly is known by the browser. I.e. the bank/PSP (which also isn't a browser), would be the most likely Verifier.

By relying on platform independent canonincalization you are free defining where a signature is created and verifed. For PaymentRequest there may be quite a bunch of different scenarios.

Anyway, where is the pointer to "the better" solution?

marcoscaceres commented 6 years ago

The Creator of the signature would not be a browser and is thus affected by JSON property (un)order.

Do any JSON implementations not respect the order? if so, exactly which?

cyberphone commented 6 years ago

Believe it or not, essentially none do because the JSON specification (unlike ECMAScript's specific take on JSON), says that the order of properties indeed is unspecified. That and a few other things is the rationale for the I-D.

marcoscaceres commented 6 years ago

ok, but this is still a bug in JSON spec, no? Seems the first step would be to fix the JSON spec to match browsers and developer expectation.

cyberphone commented 6 years ago

Well, it is has been like that since the inception of JSON. Changing it would be a major deal since many JSON systems (including Java and C#) rely on reflection which also enumerates properties in an unspecified order.

I agree that it is strange that if you declare the objects A,B,C, they are typically serialized as A,C,B. Canonicalization is fortunately a simple process both to implement and apply.

I don't think you will find many programs that actually rely on JSON property order. A JSON guru would say "that's a bug" šŸ˜‚

marcoscaceres commented 6 years ago

Well, it is has been like that since the inception of JSON. Changing it would be a major deal since many JSON systems (including Java and C#) rely on reflection which also enumerates properties in an unspecified order.

Browser vendor bias here, but totally šŸ¤·šŸ½ā€ā™‚ļø.

I agree that it is strange that if you declare the objects A,B,C, they are typically serialized as A,C,B. Canonicalization is fortunately a simple process both to implement and apply.

Ok, but the above is basically an argument for getting it fixed. Obviously, legacy systems would need to be updated, but the change would be backwards compatible.

cyberphone commented 6 years ago

It will not happen because the cost is huge and the need is not that big. The IETF JSON WG wouldn't accept such a proposal.

cyberphone commented 6 years ago

As an example the Payment Request API does not depend on property order. Only a few and pretty marginal systems do. In those cases people have done special tricks like using "printf" to generate JSON.

stpeter commented 6 years ago

@cyberphone wrote:

It will not happen because the cost is huge and the need is not that big. The IETF JSON WG wouldn't accept such a proposal.

I'm confused. It seems that we (you) can't convince the appropriate working group to solve the problem, therefore we (you) feel the need to define workarounds everywhere downstream from the right place to solve the problem. That doesn't strike me as an effective or efficient approach. Am I missing something?

cyberphone commented 6 years ago

Hi @stpeter @marcoscaceres! A peek in the reference may be of some use: https://tools.ietf.org/html/rfc7159#section-1

   An object is an unordered collection of zero or more name/value
   pairs, where a name is a string and a value is a string, number,
   boolean, null, object, or array

I wouldn't characterize the (fully implemented) proposal as a "workaround", but rather an attempt creating something useful without "boiling the ocean". Since JSON doesn't even separate integers and floating point numbers, it seems that a better alternative would be CBOR but then you browser guys would get a lot of new work which also isn't an option, right?

I have found that JSON (and JavaScript) can do [almost] everything you want although it sometimes looks a bit on the ugly side.

cyberphone commented 6 years ago

There is actually a current and "similar" proposal with Microsoft as well as me as authors, building on ECMASrcript property order: https://tools.ietf.org/id/draft-erdtman-jose-cleartext-jws-00.html

After having checked with major tool vendors as well as getting negative feedback in the JSON WG, I changed my mind and turned to canonicalization which doesn't have to be natively supported in parsers and serializers to work.

Less than 30kb: https://github.com/cyberphone/json-canonicalization/tree/master/java/canonicalizer#json-canonicalizer-for-java

cyberphone commented 6 years ago

You may now try it. It takes seconds. https://mobilepki.org/jws-jcs/home

adrianhopebailie commented 6 years ago

@marcoscaceres and @stpeter, the issue raised by @cyberphone is entirely valid and a major reason why JOSE sucks as much as it does for signatures (the signature is applied to base64 encoded data which must be decoded and compared to any clear JSON to ensure they are actually the same data).

It has been the source of major vulnerabilities in JOSE signatures and also part of the reason so many people immediately recoil if you say you want to use JOSE as your signature standard.

Because of history, there is no guarantee that JSON parsers respect ordering unless they are compliant with the very latest ECMAScript specs.

Critically, the fact that browsers do respect ordering is irrelevant because it is not just browsers that will create and validate the signatures that may be included in Payment Requests.

I would suggest that this issue remains closed and a new one is opened under the encryption and tokenization TF to suggest the use of detatched signatures as an alternative to JOSE for the WG to consider in exploring standards for encryption and signing.

stpeter commented 6 years ago

@adrianhopebailie wrote:

It has been the source of major vulnerabilities in JOSE signatures

Citation needed. As I understand it, the major vulnerabilities have been related to key handling.

Some of these matters are more carefully specified in the COSE (not JOSE) standard, so we might want to look at that for tokenization and encryption. See you over there. :-)

adrianhopebailie commented 6 years ago

https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/

The issues with JWS are that you can:

  1. Send a header that specifies the "none" algorithm be used
  2. Send a header that specifies the "HS256" algorithm when the application normally signs messages with an RSA public key. (i.e. Use the public key as a secret)

Further, as I understand it, the issue with the Base64 encoding is that the recipient will validate the signature over the Base64 data but often will not validate that the Base64 data is the same as the unencoded JSON data they have been provided along with the signature. It's a foot gun.

cyberphone commented 5 years ago

With the new work item https://www.w3.org/securepay/charter.html the W3C will probably return to this issue