w3c / payment-request

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

Changes resulting from 28 February PING privacy review #843

Closed ianbjacobs closed 5 years ago

ianbjacobs commented 5 years ago

@rsolomakhin, @danyao, @marcoscaceres,

Based on discussion at the Privacy Interest Group call yesterday, I took an action to propose some changes; see the minutes for details: https://www.w3.org/2019/02/28-privacy-minutes

Specifically:

The following tasks have been completed:

NOTE: I will also point PING at the edit.


Preview | Diff

npdoty commented 5 years ago

Combining the privacy and security considerations section and the privacy considerations section has one problem: the high-level category is listed as non-normative, but some of the subsections have normative requirements in them. I think you could fix that by removing the marking of the high-level section as informative, and then evaluating each subsection to see whether it's informative or normative.

ianbjacobs commented 5 years ago

@npdoty, thanks for catching that. I have adopted your proposal. I do not believe I have changed what was already the case - a single normative section under Security and Privacy Considerations.

marcoscaceres commented 5 years ago

Thanks for making a start on this! I’ll try to review it over the weekend.

pes10k commented 5 years ago

Thanks much for these @ianbjacobs.

1) Under mitigations / protections, I'm wondering if there isn't the possibility for greater protections / stronger suggestions here. For example, is there any plausible any scenario where multiple iframes would need to call the canMakePayment endpoint in the same top-level context?

2) What are the avenues for suggesting / proposing that the mitigations become normative?

3) @samuelweiler had suggestions / concerns about the current proposal and negotiating what payment fields are shared (looks like the options argument would be a natural fit). Will that be part of these changes?

Thanks much!

ianbjacobs commented 5 years ago

HI @snyderp,

Under mitigations / protections, I'm wondering if there isn't the possibility for greater protections / stronger suggestions here. For example, is there any plausible any scenario where multiple iframes would need to call the canMakePayment endpoint in the same top-level context?

That was one of the suggestions from the call that made it into the pull request: to limit in the face of multiple calls with different parameters from the top-level browsing context. Are there concrete text suggestions you have for making that clearer?

What are the avenues for suggesting / proposing that the mitigations become normative?

We can continue to discuss them on this thread. I think if the implementers agree that a given mitigation should be standardized, then I expect we can add it. However, I would not expect that to happen in version 1.

@samuelweiler had suggestions / concerns about the current proposal and negotiating what payment fields are shared (looks like the options argument would be a natural fit). Will that be part of these changes?

I would not expect negotiation of which data is shared to be a version 1 feature of Payment Request API. That has not been part of the specification to date and I think we would need to have more discussion of real-world payment systems. Sam has opened a new issue where have started discussion: https://github.com/w3c/payment-request/issues/842

A related topic (outside of Payment Request API) involves device fingerprinting (through JavaScript and other mechanisms). Our ongoing discussions in the working group involve topics like how to manage user privacy preferences with demands for data from risk engines.

Ian

pes10k commented 5 years ago

@ianbjacobs

That was one of the suggestions from the call that made it into the pull request: to limit in the face of multiple calls with different parameters from the top-level browsing context. Are there concrete text suggestions you have for making that clearer?

I see the "For example, a user agent may restrict the number of successful calls that can be made based on the top-level browsing context" text. I'm not sure I understand the "successful calls" text there. Whats an "unsuccessful" call? If "unsuccessful" means canMakePayment returns false, then merely rate-limiting on "successful" calls won't do much to reduce its finger-print-ability. Apologies if I'm miss understanding but could you explain / clarify whats meant here?

A related topic (outside of Payment Request API) involves device fingerprinting (through JavaScript and other mechanisms). Our ongoing discussions in the working group involve topics like how to manage user privacy preferences with demands for data from risk engines.

Great! Where is the best place to stay up to date on these discussions?

ianbjacobs commented 5 years ago

Hi @snyderp,

I'll start by saying that this topic has been a challenging one for the Working Group, and new ideas are welcome. We are relying on implementaitons to help mitigate abuse while at the same time responding to merchant requirements to be able to decide what checkout experience they can provide that will afford the least friction.

The particular text that you are referring to no longer exists in my pull request. However, it may be that you have the same question over the new text.

I invite @marcoscaceres, @rsolomakhin, @danyao, and @aestes to weigh in on their implementation experience.

There have been other ideas on this topic that have not gained traction for other reasons; see #777 for example.

Regarding data gathering for risk analysis, that seems to lie partly within the scope of several W3C groups. The Web Payments WG has had some discussions with EMVCo about 3-D Secure, which gathers some data. We've also chatted with the Web Authentication Working Group about whether WebAuthn (e.g., attestations) might be helpful in reducing reliance on JavaScript. And FIDO and EMVCo are also discussing that topic.

To help facilitate some of these conversations we have been discussing the creation of a W3C Interest Group on Web payment security. A draft charter was reviewed by the W3C Membership, EMVCo Board, and FIDO Board; we are currently addressing feedback.

In short: I would like to make it easier to discover and participate in Web payment security topics. I hope this proposed IG can help fulfill that goal.

pes10k commented 5 years ago

@ianbjacobs

Thanks again for the reply. Sure enough, i was looking at the wrong text. Thanks for the clarification!

One other item related to mitigations, and one more reason you may want to include mitigation standardization in v1 (even if it slows things down): how does the user agent signal to the website "I am interested in using the Payment API, but I don't want to allow the fingerprinting risk implied by canMakePayment."?

Say the user agent is operating in this privacy-protecting state and takes some of the mitigation steps mentioned in the text, and turns canMakePayment off (e.g. "allowing the user to configure the user agent to turn off"). Is there some way the UA can say "ask me explicitly what I support, by sending me a form, or similar, but no passive techniques"? I dont see anyway to express this in the API as described.

Throwing SecurityError seems semantically wrong (there is no security related issue in this scenario). The NotAllowedError is only specified for the rate limit case. And in either case, the website might reasonably interpret the response to be "UA never allows using Web Payment API" or "i've been rate limited", instead of "UA doesn't allow the website to ask what payment methods are supported, passively." In which case, the canMakePayment functionality, as currently imagined might increase friction (since the site could assume Web Payments is disabled).

I suggest adding an additional exception type, or return value to the canMakePayment promise indicating "user is still interested in Web Payments, but no background / passive checking, to maximize use of Web Payments API. Thoughts?

marcoscaceres commented 5 years ago

I suggest adding an additional exception type, or return value to the canMakePayment promise indicating "user is still interested in Web Payments, but no background / passive checking, to maximize use of Web Payments API. Thoughts?

The use case remains that "can make payment?" is intended to be used to present, for example, an Google Pay specific button directly in the web page. Asking the user is not practical, because the site is effectively "port scanning" what supported payment methods are.

I think the only feasible solution here is for the user to have control over this (like Safari does). Basically, an opt-in this check:

"[ ] Tell sites I support "basic-card" (when not in Private Browsing mode)."

marcoscaceres commented 5 years ago

This is how Safari works:

screenshot 2019-03-05 16 12 37

pes10k commented 5 years ago

@marcoscaceres

I dont we're disagreeing. The correct answer is definitely to prompt, and to effectively not allow anything like how canMakePayment is designed. We discussed this on the PING call.

But, whether or not canMakePayment comes out or always leads to a prompt, or whatever else, i'm saying there needs to be more granularity in the reason the user is not returning accurate info on canMakePayment. That there needs to be a way to explicitly say to the site "i'm not going to tell you the payment methods I support passively, but I would still like to use the Web Payments API checkout flow."

marcoscaceres commented 5 years ago

That there needs to be a way to explicitly say to the site "i'm not going to tell you the payment methods I support passively, but I would still like to use the Web Payments API checkout flow."

heh, returns "maybe" :) But seriously, it's why in Firefox we always lie and just return true.

pes10k commented 5 years ago

@marcoscaceres that seems like a reasonable approach, but suggests it shouldn't be in the standard in the first place :)

Brave will very likely do something similar. Is anyone familiar with what Safari is planning on doing for non-Apple pay methods?

aestes commented 5 years ago

Is anyone familiar with what Safari is planning on doing for non-Apple pay methods?

Currently, Safari's only supported payment method is Apple Pay.

rsolomakhin commented 5 years ago

@snyderp wrote:

Whats an "unsuccessful" call?

Rejecting canMakePayment with NotAllowedError and a message Exceeded query quota.

pes10k commented 5 years ago

Currently, Safari's only supported payment method is Apple Pay.

Thanks! I should have asked differently though: Does anyone know who, other than Chrome, plans to implement the spec / canMakePayment as described in the document? Sounds like definitely not Firefox, definitely not Brave, and maybe not Apple?

rsolomakhin commented 5 years ago

@snyderp : Which part of the spec differs among the implementations?

From https://w3c.github.io/payment-request/#canmakepayment-method :

If the user agent has a payment handler that supports handling payment requests for identifier, resolve hasHandlerPromise with true and terminate this algorithm.

Firefox has a built-in payment handler for "basic-card", so they will always return "true". @marcoscaceres, correct me if I'm wrong. So Firefox implementation seems to match to spec, right?

ianbjacobs commented 5 years ago

Adding @romandev and @zouhir (and assuming @rsolomakhin and @danyao already watching).

Ian

rsolomakhin commented 5 years ago

@snyderp wrote:

I suggest adding an additional exception type, or return value to the canMakePayment promise indicating "user is still interested in Web Payments, but no background / passive checking, to maximize use of Web Payments API. Thoughts?

I like this idea. Our current behavior in this case is to return "false" in canMakePayment(), but a different error message would definitely be useful.

ianbjacobs commented 5 years ago

@snyderp and @rsolomakhin, would you support creating a new issue on the topic of finer-grain error reporting when canMakePayment() returns "false"?

Some observations (which I can carry over to a new issue as well).

Ian

rsolomakhin commented 5 years ago

@ianbjacobs : A separate issue sounds good. Does this need to go into the spec or best practices for implementers? I understand the error codes go into spec. Not sure about error messages.

Other scenarios that would benefit any payment handler or merchant:

  1. Errors in SSL. For example, self-signed SSL causes Chrome to always return "false" to canMakePayment() and reject show() with "AbortError: Request cancelled."
  2. Reasons why the payment sheet closed, e.g., "AbortError: User closed the payment handler", "AbortError: The payment handler cancelled the transaction", or "AbortError: User closed the card CVV entry form."
pes10k commented 5 years ago

@snyderp : Which part of the spec differs among the implementations?

@rsolomakhin I was basing what I said (that Firefox isn't implementing the spec as written) based on @marcoscaceres comment "But seriously, it's why in Firefox we always lie and just return true.". I take that to mean they don't follow the supportedNetworks part of the algorithm.

Brave will likely do the same (decision hasn't been 100% made yet) and return true no matter what, at least with "Shields Up".

rsolomakhin commented 5 years ago

@snyderp : Where in the canMakePayment algorithm are supportedNetworks mentioned? I was under the impression that current the spec says that Chrome, Firefox, and Edge should always return true to canMakePayment() query for basic-card, while Safari should always return true for https://apple.com/apple-pay. (Chrome is in compliance starting at version 74.)

rsolomakhin commented 5 years ago

@snyderp wrote:

Brave will likely do the same (decision hasn't been 100% made yet) and return true no matter what, at least with "Shields Up".

Sounds good. I believe that's in compliance with the spec and that's how the other implementers are behaving for canMakePayment, too, when the query is for a built-in payment handler, such as basic-card, or Apple Pay.

pes10k commented 5 years ago

@rsolomakhin

Where in the canMakePayment algorithm are supportedNetworks mentioned?

Ah, I see my error here. 3.5 says supportedNetworks doesn't matter. But in the definition of the show() algorithm, in step 15.6.1 it says canMakePayment is the result of checking the result of each handler (which would include supportedNetworks).

So, 100% my error, but would be good to rename canMakePayment the variable in the show() algorithm, to something else, to avoid confusion with the canMakePayment method. isHandlerSupported? Thoughts?

This is even more confusing because the canMakePayment note says "[canMakePayment checks if] the user agent supports any of the desired payment methods". When I click on payment methods, i'm taken to a link that says "the party that provides the means (e.g., credit card) that the payer uses to pay". Since "Visa" and "Mastercard" are parties, but "a credit card" is not a party, the "NOTE" text seems to suggest the canMakePayment text is describing "does the user agent have a visa card set up" and not "does the user agent have a credit card" set up.

On looking closer, i see that "payment method" is in bold, followed by provider (not in bold), so I'm left even more confused whether this is a definition of a payment method, or a provider of a payment method (and if so, why was I was linked here? and I still don't know what a payment method is).

I suggest cleaning all this up, and explicitly defining more terms. I see that I've misunderstood what canMakePayment (method, not the variable) is intended to do. But I hope I've shown why the document isn't helping ;)

pes10k commented 5 years ago

@rsolomakhin @ianbjacobs

Just so that my understanding is clear, can someone describe what canMakePayment should return in each of the following scenarios:

  1. I'm using Firefox, I haven't ever used any Credit Card info in FF (i.e. it doesn't know if I have a visa). Website calls canMakePayment with credit-card and visa.
  2. Same as above, but I've disabled Payment Request API (dom.payments.request.enabled = false)
  3. I'm using Firefox, but `supportedMethods = "apple-pay".

@marcoscaceres just trying to understand what you mean by "FF lies…". Can you describe what you meant there?

rsolomakhin commented 5 years ago

@pes wrote:

@rsolomakhin, Just so that my understanding is clear, can someone describe what canMakePayment should return in each of the following scenarios:

  1. I'm using Firefox, I haven't ever used any Credit Card info in FF (i.e. it doesn't know if I have a visa). Website calls canMakePayment with credit-card and visa.

According to the spec, FF should return true for canMakePayment here, because the built-in basic-card payment handler is available for use.

  1. Same as above, but I've disabled Payment Request API (dom.payments.request.enabled = false)

Not familiar with dom.payments.request.enabled. @marcoscaceres ?

  1. I'm using Firefox, but `supportedMethods = "apple-pay".

According to the spec, FF should return false for canMakePayment here.

marcoscaceres commented 5 years ago

@snyderp, @rsolomakhin

According to the spec, FF should return false for canMakePayment here.

Yes, you are correct - sorry... I wasn't very clear and didn't give enough context in my response above. The original canMakePayment() worked in the same way as the proposed hasEnrolledInstrument() - that is, "supports PMI AND has enrolled an instrument". We used to lie about having the enrolled instrument (because it further adds to finger printing)...

So, basically we were returning true for only known PMIs (of which Firefox knows only about "basic-card").

So, @snyderp, to answer your questions.

I'm using Firefox, I haven't ever used any Credit Card info in FF (i.e. it doesn't know if I have a visa). Website calls canMakePayment with credit-card and visa.

True.

Same as above, but I've disabled Payment Request API (dom.payments.request.enabled = false)

False.

Note dom.payments.request.enabled would literally turns off the entire API... so rather, you would get a "canMakePayment() is no a function" JS exception.

I'm using Firefox, but `supportedMethods = "apple-pay".

False.

rsolomakhin commented 5 years ago

@snyderp wrote:

I suggest cleaning all this up, and explicitly defining more terms. I see that I've misunderstood what canMakePayment (method, not the variable) is intended to do.

SGTM

aestes commented 5 years ago

This is how Safari works:

screenshot 2019-03-05 16 12 37

I should clarify something here. This option influences the return value of the canMakePaymentsWithActiveCard API in Apple Pay JS (and soon the hasEnrolledInstrument API in Payment Request).

When that option is unchecked (or the window is in Private Browsing), canMakePaymentsWithActiveCard will behave as if canMakePayments were called instead, returning true whenever Apple Pay is supported even if there are no enrolled instruments.

Neither this checkbox nor Private Browsing influence the result of canMakePayments in Apple Pay JS or canMakePayment in Payment Request.