-
Notifications
You must be signed in to change notification settings - Fork 42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open Window Algorithm and tracking through 1ps #351
Comments
Hi @snyderp, Thanks for raising an issue. One quick note: the merchant does not open the payment handler. The user chooses I have a couple of questions:
Thanks! Ian |
Howdy @ianbjacobs!
It depends on the details of those redirection flows, how deeply nested they are, etc. Safari, for example, prevents some sites that are part of redirection flows from keeping state (ITP2.x) (those that it thinks are tracking). Brave and Safari both strip query params from some URLs to prevent sites from pushing information between 1p contexts. There are browser extensions that do similar things, and other browsers may, or may plan to, do other things that I'm not familiar with. So, its all depends, but the overall point is that if payment.com is opened up from example1.com, and also opened from example2.com, payment shouldn't be able to link those two events from that activity alone.
Not all visits to the checkout / payment page result in entering information (some users decide not to purchase). And some visitors may want to maintain different identities with the same payment provider, so (for a variety of reasons) may choose to present one identity payment.com when buying boring things, and might present another identity to payment.com when buying sensitive things. (e.g., paying for insurance and paying for a cancer screening). |
hi @snyderp,
So an interesting question is: what information can be sent by the merchant to the payment handler once the user selects the payment handler to pay? The Payment Handler API defines some data for the browser to hand to the payment handler. This is data deemed necessary for the transaction to take place: The browser passes the origin of the merchant site (and the origin of the party that called Payment Request API, e.g., if from an iframe). In addition, a payment method definition can include its own "request data" (e.g., information to identify the merchant to the payment handler).
That would be the same as if the user were to cancel the payment handler before completing payment.
I believe that the payment handler approach would support that use case. A (Web-based) payment handler is a Web site, so the user should be able to interact with it with different identities. |
My concern isn't related to the information that can be exchanged, its related to which storage the web payment handler context receives. If the frame is a 1p context, that will allow for tracking to occur across 1p pages. If its a 3p context (and so all the restrictions placed on nested contexts would apply) then most methods of tracking are prevented.
Again, my concern is not whether the API would allow people to long in with multiple identities, its that the spec, as written, would allow the payment handler to link those multiple presented identities together (since they're all happening in the same storage context). Having the context be 1p / top level makes that possible; having it be 3p / nested-context prevents most methods of that, since the storage the payment handler context gets when opened from store1.com would be distinct from the storage the payment handler context gets when opened from store2.com |
Would this mean that I have to login into Google Pay separately on each merchant website? |
By default yes (the same storage that allows not-logging-in also enables tracking)
So, well behaved sites would not require multiple logins |
Thanks @snyderp for raising these thoughts. I understand the importance of locking down 3P iframes. Where I respectfully disagree is that the payment handler is not a 3P context the same way iframe is. It's more like a nicely positioned popup because:
I'd argue that the payment handler window is not fundamentally different from a new tab that's triggered by the user clicking on an
If I click on a link to ewallet.com from store1.com, log in with account1, and then click on a link to ewallet.com from store2.com and log in with account2, ewallet.com can also link my two identities. Being able to follow links is a fundamental property of the web. The only question is, how different is the payment handler pattern different from following links? I'd argue it's pretty similar, because user sees a "Pay with eWallet" button, clicks on it. It shouldn't be a surprise to them that we load a page from ewallet.com. Other features of the Payment Handler API arguably needs more thought. For example, the Just-in-Time Install feature causes the browser to download a manifest from a payment app origin that's specified by the merchant, without user guesture. However, Chrome's implementation doesn't send any cookies on this request. I believe we also don't allow setting any cookie on the response, but need to check. If it does, it's a bug and we'll fix it. A bad actor can trick the user into clicking on something that opens a payment handler window to accomplish tracking. But the effect is very intrusive, so it doesn't seem to me that it will be a very successful exploit. Also browsers implementing the payment handler window can monitor how origins use Payment Request API. If there's good reason to believe this API is not used for legitimate e-commerce use cases and can prevent these attacks similar to how Safe Browsing works today. |
The difference is that different tabs / 1ps cannot communicate with each other. Thats exactly how cross site tracking is accomplished, and what 3p containment protects against. You can test this, for example, by clicking a cross-domain
I don't understand this claim That is not true with out some common hook to tie account1 to account 2. If you have segmented (3p) storage, the ewallet.com lacks that common hook. But further, consider other types of tracking you're enabling:
This is not at all like following links on the web. Tracking user across link clicks is currently accomplished by using the referrer header and / or query parameters. Browsers (Safari, Brave, Firefox) are all working on ways of preventing exactly this. The proposal as is would re-introduce the privacy harm currently being worked on / solved by these platforms. The issue here has nothing to do with following links, and all about what 1p contexts can learn about the behavior of the user in other 1p contexts. |
In general I agree that there needs to be more control over arbitrary cross-origin communication. I'm still learning the different mechanisms. Thanks for being patient with me.
This is what I was thinking:
I feel I'm missing some key insight to understand why segmented storage helps here. Would you help me understand? Assuming the cookie ewallet.com sends back to store1.com contains some ID for the user that ewallet.com understands, and it's this cross-origin transmission that allows tracking, why can't ewallet.com and store1.com accomplish the same via a server-side backend communication? This should be possible since we already assume they are colluding.
I agree theoretically you could do this. However, I suspect the fact that the tracking is not completely seamless (because a modal will open) would make this not a very useful mechanism to deploy trackers. We can make it even harder by having the browser require another user gesture inside the payment handler modal to dismiss the modal. This will not add any friction to legitimate use cases but would make an attempted attack very visible to the user. If this experience persists, they probably wouldn't come back to the site again. I feel this may be a sufficient disincentive for this abuse of payment handler.
Removing referrer header seems a reasonable proposal. How would removing query parameters work? Would I no longer be able to link to a page with query parameters? |
Segmented storage prevents this kind of tracking because when ewallet.com is a 3p of store1.com, it gets a separate cookie jar (and other storage) than when ewallet.com is a 3p of store2.com. The distinct cookie jars (sometimes called double-key-ing storage, since
Unfortunately, the web platform is full of privacy harms that start exactly this way "sure its possible, but no way anyone would ever use it". Partial list includes etags, HSTS cookies, communicating across tabs using nested iframes, 1000 different sources of fingerprinting entropy, etc etc etc etc. If there is a way to track, you can be sure someone, somewhere will use it
This differs by browsers (Safari strips all query params when the user is coming from a labeled tracking domain, Brave ships a set of query params used by known trackers, etc), but is getting increased focus. There is no perfect solution right now, but things are in a "lets not make the problem worse while we try to solve it" scenario. |
I think the problem boils down to this: both legitimate payment handlers and trackers would want to access 1P storage with minimal user friction. Browsers need to allow legitimate use cases while blocking trackers. Segmented storage blocks 1P storage by default and relies on browser heuristics to remove as much user friction as possible for well-behaved websites that use Storage Access API. For example. Safari suggested automatically granting What about this alternative approach: instead of blocking storage access, browser can use an algorithm similar to that for granting storage access [3] to block I believe this is better than the segmented storage approach in two ways: Browser can work with the user to “vet” payment apps that they trust. For example, browser can show a permission prompt when installing a payment handler with something like "Do you wish to install https://ewallet.com as a payment method that you can use across the web?" An affirmitive answer would allow this payment app to be loaded in the open window algorithm. Or, browser can prompt the user when While this model still allows some communicaton between 1P contexts (i.e. the merchant context and the payment app context), the user vetting process above limits the capability to only payment apps known and trusted by the user. Also because the communication is via Payment Request API instead of the generic postMessage, this leaves room for browser to detect and restrict abuse. Lastly, we’ll make sure all the obvious loopholes are closed in the Payment Handler API, i.e.: [1] whatwg/html#3338 (comment) |
I don't see anything about "automatically granting". The user gesture part is a requirement, but isn't access itself.
The browser doesn't need a long list of new, hard to reason about, hard to compose guesses for when privacy isn't needed. I appreciate, from your perspective "what's one more little exception", but that is the way that privacy on the platform will continue to crumble; a long list of growing exceptions. More specifically, can you say how your proposal for
Can you say more about this? Any communication channel can quickly be converted to transmit arbitrary data |
I'm referring to this part of @othermaciej's comment: "Although prompting is allowed by our proposal, we expect in most cases we will just grant the permission without prompting, as the user action is sufficient. We will prompt only if we suspect some funny business is going on, and even then we may just choose to always deny."
I understand we don't want yet another straw. I care very much about Payment Handler API not being abused for non-payment use cases. Suppose I can distinguish perfectly a payment use case from others, and only allow a legitimate payment app to use the open window algorithm to access 1P storage, would you still consider this a privacy hole? What I'm trying to understand is whether the concern is the abuse potential of the API or whether you don't see any legitimate use case at all.
The main difference is that the proposal can reject From the user's perspective, the difference can be much smaller. In both cases, the user clicks on something and then sees a permission prompt with some message. I'd prefer reusing the same prompt UI if possible because it seems less confusing to users. I'll need to talk to our UX folks.
Admittedly this idea needs more exploration. My initial thinking is that the Payment Request API is designed to serve a specific use case, so we may be able to leverage domain specific knowledge to prevent abuse. For example, we can use signals such as the total amount, completion rate to check if a payment handler is likely real or not. Browsers can also develop heuristics for detecting e-commerce websites and known payment apps and block suspicious "payment handlers" similar to Safe Browsing. |
Ah, thank you for pointing that out. I did not catch that, my error. However, I don't think something like that can be embedded in a spec, w/o defining what "funny business" is, and the privacy of a spec shouldn't turn on unstated heuristics of what "funny business" is, so I think it best to focus on the algorithm described in the spec.
The concern is (i) the abuse potential, and (ii) the worry about adding privacy debt to the platform through something that gets misused in a way we can't foresee. So, I'm not saying that there's no legit use cases, or that there is no way to get the feature safe, just that there should be a strong precautionary principal in place (and that "lets make an exception for my feature" is a common thing I hear, that is definitely not inline with caution, not saying that thats what you said :).
The concern here is that there doesn't seem to be a way that I can use the payment handler w/o giving it 1p storage. E.g. I have to give the context all or nothing, where 2y'd storage is in place to prevent putting users in this situation. Is there a way you can structure / order things where I can use the payment handler, w/o giving 1p storage? The
I would be interested in hearing more, but in general, I think you should start with the assumption that that any communication channel can ultimately be leveraged for arbitrary communication. Also note that any heuristic that depends on "did X match Y" or similar has likely already let some information pass and the cats already out the door… |
The current algorithm as described in [1] leaves prompting to browser discretion. I think this is refers to browser's heuristic on detecting "funny business". [1] https://developer.mozilla.org/en-US/docs/Web/API/Document/requestStorageAccess
I agree with both of your goals. I think the best next step is to elaborate on the privacy / security model of Payment Handler API, and enumerate, as exhaustively as possible, privacy attack vectors. Then we can decide if 3P storage are an effective mitigation to these threats. Separately, I'll also start documenting payment app use cases that will be significantly impacted if payment handler window becomes a 3P context. I hope this will allow us to make a pragmatic decision. FWIW, I think a pragmatic decision is important. The web doesn't exist in an vacuum. The web will be out-competed by other platforms if it either fails flatly on privacy or if makes it impossible to build important user journeys. If I may just get a little philosophical, I feel payments is very important to the web, because the web's lack of a proper monetization model is part of what incentivized pervasive tracking. A secure, privacy-sensitive and low-friction payment primitive will allow content creators to monetize directly instead of relying on personalized ads.
Why should the payment handler be treated differently from a popup window, which has 1P storage?
The main use case I was worried about is using the same payment handler across all sites. I worry that if browser is required to prompt the user on every {website, payment app} combination, this will be a bad user experience. But I've never built a payment app buyflow, so maybe this is solvable. This is why I'd like to work with a real payment app to gain more nuanced understanding of the problems here. The documents I promised above should help me develop a more informed opinion.
Acknowledged. To summarize, I think the best way to move this discussion forward is to do the following:
Given that these tasks will take some time, one way we can limit the impact now is to move Payment Handler API behind Origin Trials [2]. Do you have a strong opinion about this? |
This is not correct, popup (window.open) windows have partitioned storage, at least in the Safari implementation. I have not checked Firefox's or other's implementations.
I appreciate that this might just be a difference of opinion, but being asked, once per
I would prefer that Google (or anyone else) not ship functionality on the web with known privacy holes, but I also realize that I don't have (nor probably should I have) any say on what Google does. I'm only here to make sure the spec winds up privacy-preserving. One thing I would strongly emphasize though is that Chrome doesn't currently do any storage partitioning, doesn't implement Storage Access API, and has stated that it doesn't intend to ship it. So, Chrome users' experience with the API you might be putting behind origin trials may not (will not?) provide one-to-one feedback into the spec (which would presumably be implemented by folks who are, or will be, shipping Storage Access API). |
This is news to me. Thanks for pointing it out. I'll look into Chrome's position on this one.
I appreciate the discussion.
I'm not following your point. The learnings I'm looking for are (i) the degree of reliance on cookie for a legitimate payment handler implementation (ii) user's ability to make sense of the security UX features of the payment handler window (e.g. URL, origin) and (iii) importance of explicit payment handler installation flows. I believe all of these are independent of whether Chrome implements Storage Access API, right? |
Could be that my point is totally wrong :) But I took you to mean that origin trials would give you feedback on whether 1p cookie jar is needed, whether storage access API prompts were appealing / tolerable / intolerable to users, etc, and since Chrome in some cases is, and in more cases soon, will be doing its own thing regarding 1p vs 3p and Storage Access API, I didn't know how "generalizable" the feedback from the origin trials would be. But if I'm misunderstanding or off base, please, disregard :) |
Ah I see. You're right, the prompt friction of Chrome's specific UI will not be generalizable. I need to figure out what Chrome will be doing on Storage Access API. I think knowing how critical is 1P cookie jar to payment flows, whether there are workable alternatives in a 3P context, and the general user perception of payment handler window may be transferrable lessons. |
I had a couple thoughts that I hope might be helpful:
|
If I'm understanding the idea @jyasskin, I don't think it addresses the issue. It should be possible to use the same payment handler, on two different sites, without the payment handler automatically linking those two accounts (e.g. i want to use the company card on one site, and my personal card / persona / whatever on the other site). Treating "request a payment event" as synonymous with "requestStorageAccess" when using the payment handler API would defeat the above possibility. There is an opportunity here to enable convenient payments for users (Payment API win), w/o enabling account linking (privacy win). Treating the payment handler as a 1p context (or else get shunted to iframes / old way of doing things) boxes out that possibility. Again, if im understanding the proposal right |
In (3) I was suggesting that "requestStorageAccess" be a sub-step of "request a payment". So, if a user chose to deny storage access, the payment flow would continue without any first-party cookies or storage. This would probably need to avoid the payment handler's service worker, so it might need some API changes, but I think those could be limited to providing a URL to be loaded as a third-party to let the user enter their payment information. |
From discussion with @snyderp @marcoscaceres @aestes @rsolomakhin @ianbjacobs yesterday, I believe we reached the following consensus:
For both (b) and (c), Chrome, Firefox and Safari all indicated desire to reuse the same prompting strategy as the respective Storage Access API implementations. Implications to the Payment Handler API:
Implications to payment handler developers:
Implication to users:
Other noteworthy points discussed:
Next steps:
|
thanks @danyao ! Some other thoughts / questions:
|
Good question. My assumption is that identity is pretty crucial to payment apps so they would all want to use 1P storage, so the proposal above optimizes for that path. But it does seem to be a drawback if there are real payment handlers that want to opt-out of prompting. Maybe we can add an optional
I don't have the full details on this. Your best bet is probably to ask on whatwg/html#3338. I'll make sure when it's available, Chrome's Payment Handler implementation will hook into that. |
A payment processor accumulates information about merchants and users anyway. Vetting is (IMO) the only way forward because a compromise will most likely leave everybody unhappy. Adding a set of "consents" which 99% of the user base do not understand the consequences of seems like a repeat of the pretty failed cookie consent thing. FWIW, vetted native payment handlers like Apple Pay and Saturn are also domain agnostic which give them a clear edge over |
I thought this issue was resolved? Is it still waiting for the spec to be updated? cc: @danyao |
Hi @pes10k, The Working Group considered a number of proposed changes recently (at it's virtual meeting last week) including this one. There are a set of specification changes that I anticipate will be made, including related to this one. Ian |
Updating the spec has been blocked on the |
I see, I'll wait to hear the result of that, but the outcome i thought we agreed to is doing more than just asking for consent; its designed to make sure that profile data isn't joined unexpectedly, etc. in a way thats compatible with dual keying storage and storage access api |
I'll definitely keep you posted. This earlier comment is still the best capture of our agreement. |
@danyao wrote "legitimate payment handlers". This definition remains a problem. Assume that you want to create a wallet. That is, a This is already a fact for native payment handlers like |
The following example of a VRP (Variable Recurring Payment) for a Saturn-based phone-subscription request, highlights another limitation of the current approach to payment handlers. VRP is also a part of future Open Banking APIs. {
"amount": "360.00",
"currency": "EUR",
"nonDirectPayment": {
"type": "RECURRING",
"interval": "MONTHLY",
"fixed": false,
"expires": "2022-04-13T00:00:00Z"
},
"referenceId": "754329",
"timeStamp": "2020-04-12T06:04:12Z",
"expires": "2020-04-12T06:35:00Z"
} To cope with this scenario, Saturn only uses Of course you can deal with VRP outside of This specification talks about "fake" payments so I'm in "good company" 😇 |
I am attempting to understand the "Open Window Algorithm" section of the spec. My understanding is that it would allow (say) example.com to open and interact w/ 3p domains (those of the payment handlers) but in a 1p / top-level-context.
If Im reading this correctly, this would enable types of tracking that other parts of the web platform are trying to address (specifically, double-keying, or partitioning, storage by 1p-3p to prevent the 3p from tracking the user across the web). If I read the spec correctly, the standard would allow the payment processor to track the user across pages that use the processor, since the processor would always have access to the same global storage, instead of different storage for each 1p it appears under.
Updating the spec so that open window doesn't create a top-level-context, but a 3p context, would solve this problem, and would be inline with the privacy protections being pursued by partitioning storage, Storage Access API, etc.
The text was updated successfully, but these errors were encountered: