secure-payment-confirmation icon indicating copy to clipboard operation
secure-payment-confirmation copied to clipboard

Proposal: Enhancement - Opt-out link

Open jcemer-stripe opened this issue 2 years ago • 18 comments

Background

In May 2021, the European Data Protection Board (EDPB) published recommendations [0] dealing with the storing of credit card data by online providers of goods and services, for the sole and specific purpose of facilitating further purchases. These recommendations note that “consent (Art. 6(1)(a) GPDR) appears to be the sole appropriate legal basis for the above-described processing to be lawful”.

The EDPB also noted that “[a]ccording to the Article 7(3) GDPR, the data subject shall have the right to withdraw his or her consent for the storing of credit card data for the purposes of facilitating further purchases at any time. The withdrawal must be free, simple and as easy for the data subject, as it was to give consent.”

[0] https://edpb.europa.eu/system/files/2021-05/recommendations022021_on_storage_of_credit_card_data_en_1.pdf

Proposal

To enable compliance with applicable laws relating to the collecting and withdrawal of consent, the proposal is to provide a customizable text field on the payer-facing SPC authentication screen to accommodate the inclusion of appropriate language and links to address applicable requirements.

  1. Include footer field in the SecurePaymentConfirmationRequest dictionary
  2. Footer field should accept an array of footer items a. Footer item is defined as a required description and an optional link

The authentication prompt should display footer items below the payment total amount. The items should be displayed in a list format as in the mock-ups below.

A successful authentication should include the full content of the footer field in the payment field of the clientDataJSON. That ensures the payment provider can validate if the prompt was compliant.

dictionary SecurePaymentConfirmationRequestFooterItem {
    required DOMString description;
    USVString link;
}

dictionary SecurePaymentConfirmationRequest {
    required BufferSource challenge;
    required FrozenArray<BufferSource> credentialIds;
    required PaymentCredentialInstrument instrument;
    unsigned long timeout;
    USVString payeeOrigin;
    AuthenticationExtensionsClientInputs extensions;
    FrozenArray<SecurePaymentConfirmationRequestFooterItem> footer;
};

Mock-Ups

  1. Includes a single footer item with description and link.
  2. Includes two footer items: the first with description and link and the second with a short description.
  3. Includes three footer items: the first with a long description and the second and third with description and link.

image

image

image

jcemer-stripe avatar Jan 27 '22 15:01 jcemer-stripe

cc @ACathelin

ianbjacobs avatar Jan 27 '22 16:01 ianbjacobs

Assuming we are talking about 3DS, this issue seems to refer to things happening before the actual (issuer specific) authentication method is invoked. That is, a possible solution appears to rather belong to a generic part of a 3DS-enabled merchant Web application, since it (unlike SPC), indeed must handle card numbers.

I guess that EMVCo already have updated their 3DS implementation guidelines to support these requirements.

cyberphone avatar Feb 05 '22 07:02 cyberphone

@jcemer-stripe,

Thank you for writing up this issue. I have an observation and a question.

Observation: It seems the primary concern here is for guest checkout scenarios. In use cases where the user has stored a card on file and the SPC credentials are bound to that data, then presumably the user would need some mechanism to manage the card-on-file data, and an opt-out link in the SPC dialog would not be needed.

I am very uninformed about GDPR details, which brings me to the second question. There seem to be two pieces:

  • If you are able to opt in to storing some data, you need to be able to opt out.
  • The data has to be payment instrument data.

My question is: what if the relying party stores opaque information that is not credit card (or other payment instrument) data? I have in mind this flow:

  • At enrollment time, the relying party hashes credit card information and stores the hash and the credential ID.
  • At transaction time, the relying party receives the card information, hashes it, looks for a matching hash and returns any attached credential IDs.

Thus, no credit card data is stored.

Would this implementation mean that there is no requirement for an opt-out mechanism because there is no stored credit card information? Or is the requirement more generic than that: "If someone agrees to store ANYTHING then you need to allow them to request that it be deleted."

Thanks for any clarification,

Ian

ianbjacobs avatar Feb 07 '22 17:02 ianbjacobs

My question is: what if the relying party stores opaque information that is not credit card (or other payment instrument) data? I have in mind this flow:

  • At enrollment time, the relying party hashes credit card information and stores the hash and the credential ID.
  • At transaction time, the relying party receives the card information, hashes it, looks for a matching hash and returns any attached credential IDs. Thus, no credit card data is stored.

@ianbjacobs GDPR states that the "data subject shall have the right to withdraw his or her consent for the storing of credit card data for the purposes of facilitating further purchases at any time.". SPC is considered here a facilitator when enrolled in a checkout flow. I don't think that hashing the card number (PAN) would make the case any better.

I just want to note that despite opt-out being the trigger, the footer element can be used for other legal or operational purposes.

jcemer-stripe avatar Feb 09 '22 08:02 jcemer-stripe

These resources crossed my desk and may provide useful fodder for discussion (I still need to read them):

Regarding consent: https://ec.europa.eu/info/law/law-topic/data-protection/reform/rules-business-and-organisations/legal-grounds-processing-data/grounds-processing/what-if-somebody-withdraws-their-consent_en

Regarding keys as personal data https://www.aepd.es/en/prensa-y-comunicacion/blog/encryption-and-privacy-v-the-key-as-personal-data https://www.law.kuleuven.be/citip/blog/are-public-keys-personal-data/

See also the FIDO white paper on FIDO and GDPR: https://fidoalliance.org/wp-content/uploads/FIDO_Authentication_and_GDPR_White_Paper_May2018-1.pdf

ianbjacobs avatar Mar 10 '22 14:03 ianbjacobs

Hi Jean,

Thanks for sharing this issue, and your proposal. We (Chrome) would like to find a way to support it in SPC - but we do have some concerns.

As with many discussions around SPC, it concerns what should/shouldn't be done in browser-owned native UX (as opposed to web content). This is obviously a complex area where each browser vendor has their own views and processes, but for our part we are uneasy with the idea of allowing either:

  1. Arbitrary footer text (the description member) which could state anything.
  2. A link from trusted Chrome UX out to a potentially untrustworthy relying party site.

In general, our goal as a user agent is to make sure that the user can always trust Chrome UX, even in the presence of malicious actors. SPC has always been on the edge of this, but previously we have been comfortable that the user could not be effectively attacked via the UX (due to the WebAuthn security model). We are concerned that this proposal may cross the line into being risky for users.

We have developed an alternative proposal, which relies on the browser to send a signal to the relying party instead of sending the user to them. We'd love to hear your (and others) thoughts on it!

Proposal

Add an optional, default-false input parameter to SPC:

dictionary SecurePaymentConfirmationRequest {
    required BufferSource challenge;
    required USVString rpId;
    required FrozenArray<BufferSource> credentialIds;
    required PaymentCredentialInstrument instrument;
    unsigned long timeout;
    DOMString payeeName;
    USVString payeeOrigin;
    AuthenticationExtensionsClientInputs extensions;
    boolean showOptOut = false;  // NEW
};

The showOptOut field would be included in clientDataJSON to allow RPs to verify that it was set correctly.

When set to true, the browser will render an opt-out experience (see below for mocks). If the user elects to opt-out, then the browser:

  1. Sends the user through a WebAuthn authentication ceremony, but with the assertion type set to "payment.optout"
  2. Assuming the user completes the ceremony successfully: a. Return an error to the SPC caller, being sure to maintain authentication ceremony privacy, with no indication that opt-out happened. b. Asychronously, sends the assertion to the Relying Party via a .well-known URL, e.g. https://rp.com/.well-known/spc/opt-out.

(If step 2.b fails, the browser might retry in some way, e.g., N efforts over XY hours.)

When the relying party server receives the assertion, it can:

  1. Use the credential ID to identify which user/payment instrument the assertion is for
  2. Validate the assertion (e.g., type, nonce, etc) to its satisfaction
  3. Perform the server-side opt-out

Mock-Ups

Using stripe.com as the RP and an example test merchant; who in the mocks is hosted on checkout.stripe.com, but in reality would be, e.g., merchant.com .

Screen Shot 2022-04-06 at 1 45 06 PM

Screen Shot 2022-04-06 at 1 45 14 PM

Screen Shot 2022-04-06 at 1 45 18 PM

Screen Shot 2022-04-06 at 1 45 20 PM

Screen Shot 2022-04-06 at 1 45 23 PM

stephenmcgruer avatar Apr 06 '22 17:04 stephenmcgruer

Hi @stephenmcgruer, let's put this on the agenda of our 14 April WPWG call. Thanks!

ianbjacobs avatar Apr 06 '22 18:04 ianbjacobs

Consolidating input from EMV 3DSWG on this issue here.

1. SPC (in 3DS Context) is an authentication method for payment. Opting out of an authentication method is a function that usually takes place through a channel that's not invoked at the time of authentication itself. For example, the end-user is not provided an option to remove their mobile number when being asked to enter the OTP sent to that mobile number. Opting-out is not similar to fall-back in our view where the end-user is asked to choose another authentication method.

2. In the most straight forward implementation of SPC with 3DS, the end-user has registration performed with the issuer and it's the issuer who will manage any process related to opting-out of that registration. Issuers can offer that through a separate channel.

3. If the end-user has registered with the merchant/PSP, the SPC authentication will be taking place outside of EMV 3DS (i.e Delegated Authentication) which takes us back to point 1 of the user opting-out of an authentication method during an ongoing authentication session. While in delegated authentication, the end-user may still be challenged by the issuer for credentials, the sequence of opt-out, fall-back (by the merchant/PSP) and then another possible challenge by the issuer could pose a lot of UX challenges.

4. This may be altogether a new pull request but reviving the suggestion of introducing a context/enumeration for which use-case the SPC API is being invoked. This can pave the way to ensure that when SPC is being invoked in use-cases where opt-outs can be managed without downstream impact (e.g non EMV-3DS), this option can be shown and vice-versa in EMV 3DS related use-cases, this option is not presented.  

stare893 avatar Apr 14 '22 14:04 stare893

I'm not quite sure that this regulation applies at all in this case.

For SPC (at least as it pertains to 3DS), credit card information <--> WebAuthn credentials is stored by the issuer, NOT by the RP or the browser. Even if this wasn't the case, I think we can still argue that the information in our particular case is NOT stored to facilitate further purchases, but rather, to help during step-up authentication (which I don't think should be in scope for this regulation to being with).

christiaanbrand avatar Apr 14 '22 23:04 christiaanbrand

For SPC (at least as it pertains to 3DS), credit card information <--> WebAuthn credentials is stored by the issuer, NOT by the RP or the browser.

For clarity: Stripe is not using the 3DS integration of SPC (at least, currently). Instead, Stripe is the Relying Party and the user is being authenticated to Stripe from merchant.com. As such, Stripe is storing the 'credit card information <--> WebAuthn credentials' mapping you mention, and have given their interpretation of regulations surrounding that in the original post.

(Side-note: did you mean PSP instead of RP here?)

stephenmcgruer avatar Apr 15 '22 02:04 stephenmcgruer

Thanks for the clarification. In that case, since Stripe has control of the website, I wonder if it doesn't make more sense to implement this particular feature as a web-feature, rather than building it within SPC. Especially since it doesn't seem like this will be required when SPC is used in 3DS mode?

(Side-note: did you mean PSP instead of RP here?)

Ah, yes. Since the PSP will also be issuing the SPC call here I figured SPC and RP are interchangeable, but strictly speaking it's the PSP (since the RP could technically also refer to the issuer since they're ultimately the ones issuing the challenge).

christiaanbrand avatar Apr 15 '22 04:04 christiaanbrand

I agree with @christiaanbrand comment that it could be built outside of SPC. Opting out usually would require end-user education and potentially them accepting some T&Cs. All that can be offered separately. Perhaps the Secure Modal Window could have a cardholderinfotext space similar to 3DS windows where some static text (instructions) could be displayed on how user's could opt-out

stare893 avatar Apr 15 '22 13:04 stare893

I guess I don't really understand why this has to be handled any differently than current 3DS challenges (this is all this is, imho). Specifically, when I go to merchant.com to buy something with my credit card from issuer.com, at some point, control is ceded to issuer.com (to do 3DS). There's no opt-out. It's just "either do 3DS and the transaction goes through" or "don't do 3DS and it's cancelled". Not sure that an opt-out in the context of 3DS makes any sense.

christiaanbrand avatar Apr 15 '22 16:04 christiaanbrand

See comment from @ljharb (probably meant for this issue) on per-merchant opt-out expectations: https://github.com/w3c/secure-payment-confirmation/issues/174#issuecomment-1071033190

ianbjacobs avatar Apr 19 '22 14:04 ianbjacobs

Hi folks; just a heads up that we have started experimenting with an opt-out flow in Chrome, to help Stripe (and any others!) determine their exact needs for an opt-out. This does not indicate (or not indicate!) that we will ship it in the future.

Our first version has landed behind a flag in Chrome 104.0.5084.0, and requires launching the browser with --enable-blink-features=SecurePaymentConfirmationOptOut, e.g.:

/Applications/Google\ Chrome\ Canary.app/Contents/MacOS/Google\ Chrome\ Canary --enable-blink-features=SecurePaymentConfirmationOptOut

There is a test page at https://rsolomakhin.github.io/pr/spc-opt-out/

The version we have implemented is different from the above proposals, so let me lay it out below:

Proposal

Add an optional, default-false input parameter to SPC:

dictionary SecurePaymentConfirmationRequest {
    required BufferSource challenge;
    required USVString rpId;
    required FrozenArray<BufferSource> credentialIds;
    required PaymentCredentialInstrument instrument;
    unsigned long timeout;
    DOMString payeeName;
    USVString payeeOrigin;
    AuthenticationExtensionsClientInputs extensions;
    boolean showOptOut = false;  // NEW
};

The showOptOut field would be included in clientDataJSON to allow RPs to verify that it was set correctly.

When set to true, the browser will render an opt-out experience (see below for mocks) in both the Transaction UX and the no-matching-credentials UX (to avoid credential probing). When missing or set to false, there is no change from the current SPC experience.

If the user elects to opt-out, then the browser rejects the show() promise with an AbortError, indicating that the user has opted out. This error is distinguishable from both the SPC 'fail' error (the usual WebAuthn error) and the SPC 'success' case (an assertion). The SPC caller should handle this error and present the user with an opt-out experience (e.g., offer to send them to the Relying Party if appropriate).

We have also discussed instead resolving the show() promise and providing an indication in the details field of the PaymentResponse, instead of using AbortError. This might be be easier for developers to detect, as there are currently multiple ways that SPC might throw an AbortError (e.g., it can also happen if two PaymentRequests are happening at once.

Mock-Ups

Using stripe.com as the RP and an example test merchant; who in the mocks is hosted on checkout.stripe.com, but in reality would be, e.g., merchant.com .

image

image

(Everything beyond this is up to the merchant)

image

image

stephenmcgruer avatar May 26 '22 15:05 stephenmcgruer

The following UI is ready for developer testing in Chrome Canary 104.0.5102.0 and later with command line flag --enable-blink-features=SecurePaymentConfirmationOptOut:

Screenshot:
Screen Shot 2022-06-06 at 10 45 02 AM

rsolomakhin avatar Jun 06 '22 14:06 rsolomakhin

An origin trial for opt-out UI is now ready for sign ups: https://developer.chrome.com/origintrials/#/view_trial/3293257227514675201.

I've registered https://rsolomakhin.github.io/pr/spc-opt-out/ for the origin trial, so the feature should work on that website in Chrome Canary (104.0.5112.0 and later) without any command line flags.

rsolomakhin avatar Jun 10 '22 14:06 rsolomakhin

During our 23 June meeting [1] we observed that this feature is not currently described in the SPC specification. The WG is keen to continue to explore this proposed approach (and the overall need for an opt-out). If further experimentation with the feature reveals that we in fact need to modify the specification to support the feature, then we anticipate adding such support after v1. I am therefore leaving the issue open but marking it as after v1. Just to be clear: we want to continue to work on this right now; but if we need spec text, we are ok with adding it after v1.

[1] https://www.w3.org/2022/06/23-wpwg-minutes#issue172

ianbjacobs avatar Jun 23 '22 15:06 ianbjacobs