canMakePayment allows information leaks/fingerprinting, invisible to the user
Reported by
lukasz....@gmail.com,
Sep 20 2017
|
|||||||||||
Issue descriptionSteps to reproduce the problem: Hi, Chrome canMakePayment has a number of interesting properties: - fingerprinting (enumerating payment methods such as whether one has a visa/mastercard/diner/etc saved in the browser) - there is no UI prompt when a payment 'match' is found so it can be made invisibly to the user A demonstration here: https://lukaszolejnik.com/stuff/cmp.html Requires having a cc added, and not being in incognito mode (which means it may also be a new method of detecting incognito). Tested on Chrome Canary, desktop/android. What is the expected behavior? 1. There should be a prompt, at least as per https://w3c.github.io/payment-request/#exposing-available-payment-methods "a successful match to a payment method causes a user interface to be displayed mitigates the disclosure risk" What went wrong? No UI display, and a site learned I included visa and/or mastercard. Additionally, in incognito mode a site knew I had all CCs included. This is made possible by the fact that canMakeRequest should be able to only query a single card (i.e. "visa") once per quota-permitted timing (30m in Chrome). So I know that the same origin testing visa and mastercard consecutively would eventually reach an exception. No exception is raised. Did this work before? No Chrome version: <Copy from: 'about:version'> Channel: stable OS Version: Flash Version:
,
Sep 20 2017
This is working as intended: one query per 30 minutes. If you find a website that's abusing the system, please report them to us. Assigning to Zach for further triage.
,
Sep 20 2017
I don't quite follow the code in https://lukaszolejnik.com/stuff/paysniffer.js. I assumed you're opening iframes in different origins, but did not see anything like that in the code. An explanation would be great, thank you.
,
Sep 20 2017
Hello cmp.html opens a frame <iframe style="width:0;height:0;border:0; border:none;" allowpaymentrequest src="https://sensorsprivacy.com/cmp.html"></iframe> and makes a test('visa'), test('mastercard') is done on cmp.html
,
Sep 20 2017
,
Sep 20 2017
,
Sep 20 2017
I'm not sure Services>Safebrowsing is a good fit. vakh: Do you think SB can/should detect cMP-abusing sites and mark them as bad in SB, or is that not something you're likely to do? Adding UI>Browser>Incognito, given the Incognito-detection aspect of this bug. Adding Team-Security-UX and estark: Do you think raising a UI would help/is feasible/would not have other bad security/privacy side-effects? I'm also not sure this is a security vulnerability; it seems like a privacy bug only. Setting labels, but keeping it Restrict-View-Google just in case. https://w3c.github.io/payment-request/#exposing-available-payment-methods says "The fact that a successful match to a payment method causes a user interface to be displayed mitigates the disclosure risk.", but I don't see a matching MUST in https://w3c.github.io/payment-request/#canmakepayment()-method. Is there a matching MUST somewhere else in the spec, or does the spec have a gap? It seems like even if we did show a UI on successful payment method match, there'd still be a privacy risk: the attacker could still enumerate what payment methods failed, and thus still learn a lot about what payment methods you have. Is that true?
,
Sep 20 2017
Skimming around in the spec a bit more, it sounds like perhaps the authors intended that a caller MUST first call `show` before it can start calling `canMakePayment`? Or, if not intended, would making that change in the spec be possible, and sufficient?
,
Sep 20 2017
Safe Browsing has no plans of doing this in the near future, so removing the SB component. > vakh: Do you think SB can/should detect cMP-abusing sites and mark them as bad in SB? It depends on how prevalent it is. I'll bring it up internally.
,
Sep 21 2017
,
Sep 21 2017
The section https://w3c.github.io/payment-request/#exposing-available-payment-methods is about new PaymentRequest(). canMakePayment() is a bit different, as it doesn't require user interaction. See the spec for it at https://w3c.github.io/payment-request/#canmakepayment()-method . I'll file a bug on tying those two sections together to make things less confusing. The intent is that the step 3 there is where we have the ability to punish such abuse. So if we're going to do something here it should be deciding when to implement step 3 and reject with "NotAllowedError" DOMException.
,
Sep 21 2017
In the above comment, s/new PaymentRequest()/paymentRequest.show(). I filed https://github.com/w3c/payment-request/issues/629 about that section.
,
Sep 21 2017
Seems you're in action. Just curious - though the issue is restricted, I would like to include a small public writeup on it. Wondering - when would it be comfortable for you? I agree with assessment of palmer@ (privacy bug, and still possible to run it even with a dialog, the issue is with quota or the perception of 'origin').
,
Sep 21 2017
By the way, I've set up a better incognito-detection PoC here: https://lukaszolejnik.com/stuff/incognito-detection.html
,
Sep 21 2017
Thanks Lukasz, assigning to Rouslan who implemented incognito/rate-limiting
,
Sep 21 2017
Following some more tests. It seems that Android version might not indeed detect incognito mode. On the other hand, payment requests with any instruments appear to always return true. If so, the fingerprinting method could then test all cards consecutively there - if all were true, one could attempt to deduce that this is in fact incognito. How likely is it that I have visa, mastercard, amex and diner (...) cards at the same time is a matter of personal preference of course. I won't say such settings are unlikely. Then again...
,
Sep 21 2017
,
Sep 29 2017
Hi, We have a bug fix incoming for enforcing the query quota in the incognito mode. It does not solve all of your concerns, but still it would be nice if we landed this bug-fix first before you disclose your findings. Would that be OK with you? Thank you. --Rouslan
,
Sep 29 2017
Can you tell a date?
,
Sep 29 2017
Let's go with 2 weeks from now: October 13. That should give us enough time to land the patch in comment #19. Does that work for you?
,
Sep 29 2017
Just wanted some clarity whether I could include this item, or go with something else. It's exactly what I need. Thanks ;) In case you decide to land the patch sooner, please ping, too. Thanks.
,
Oct 3 2017
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/16ee55201af94aa06ab450abc0fd3c39bdb31f93 commit 16ee55201af94aa06ab450abc0fd3c39bdb31f93 Author: Rouslan Solomakhin <rouslan@chromium.org> Date: Tue Oct 03 19:04:42 2017 [Payments] Enforce canMakePayment() quota in incognito mode. Before this patch, calling canMakePayment() on desktop and iOS multiple times with different payment method names and data in incognito mode would always return "true" to preserve user privacy. However, this change in behavior can be used by the website to detect incognito mode, which conflicts with the goals of incognito mode. This patch changes the canMakePayment() implementation to always check the query quota first. If the query quota has been exceeded, the canMakePayment() promise is rejected with NotAllowedError in both normal and incognito browsing modes. After this patch, calling canMakePayment() multiple times with different payment methods and data in incognito mode would return NotAllowedError after the first call. This is identical to the behavior in normal browsing mode. A website can no longer use canMakePayment() to detect incognito mode. Bug: 766973 Change-Id: Ic9bc03769e7846fc639f2a6250091aa511311c39 Reviewed-on: https://chromium-review.googlesource.com/693220 Commit-Queue: Rouslan Solomakhin <rouslan@chromium.org> Reviewed-by: anthonyvd <anthonyvd@chromium.org> Reviewed-by: Moe Ahmadi <mahmadi@chromium.org> Cr-Commit-Position: refs/heads/master@{#506130} [modify] https://crrev.com/16ee55201af94aa06ab450abc0fd3c39bdb31f93/chrome/browser/ui/views/payments/payment_request_can_make_payment_browsertest.cc [modify] https://crrev.com/16ee55201af94aa06ab450abc0fd3c39bdb31f93/components/payments/content/payment_request.cc [modify] https://crrev.com/16ee55201af94aa06ab450abc0fd3c39bdb31f93/components/payments/content/payment_request.h [modify] https://crrev.com/16ee55201af94aa06ab450abc0fd3c39bdb31f93/ios/chrome/browser/ui/payments/payment_request_manager.mm
,
Oct 3 2017
Happy the patch landed. We still wait until 13?
,
Oct 3 2017
We can make this public now. I'm marking this as "Fixed" because we've addressed a part of the issue. |
|||||||||||
►
Sign in to add a comment |
|||||||||||
Comment 1 by mkwst@chromium.org
, Sep 20 2017Components: Blink>Payments Privacy
Owner: rouslan@chromium.org
Status: Untriaged (was: Unconfirmed)