Yet another W3C API can be turned against the user, privacy boffin Lukasz Olejnik has warned – this time, it's in how browsers store and check credit card data.
As is so often the case, a feature created for convenience can be abused in implementation. To save users from the tedious task of entering the 16 characters of their credit card numbers, four for date, and three for CCV number, the Web Payments API lets Websites pull numbers stored in browsers.
Olejnik, security and privacy researcher, writes that even without a full privacy assessment, it was easy to discover some serious vectors for misuse: fingerprinting, a frequent interest of Olejnik's; and in Chrome, he found a way to reliably detect users in “incognito” mode, “a thing that generally should not be possible”.
Web Payments API is supported in Chrome and Edge, and is on the real-soon-now list in Firefox and WebKit.
The fingerprinting he discovered is quite specific: a site can detect which different cards the user may have stored. That's because while the API tries to prevent against enumeration attacks by rate-limiting the
canMakePayment call (to once every 30 seconds), that's inefficiently applied:
“A website could simply use a bunch of iframes with scripts effectively running in different origins, meaning that the 30m quota is functionally irrelevant … one iframe could test for “visa”, another for “mastercard”, etc. At the end, iframes communicate test results to the parent frame.”
The result, he writes, is that iframes could capture all the payment instruments available to an individual user.
The second issue, incognito detection, arises because incognito mode skips a rule applied to normal attempts at payment.
The vector for abuse arose, perhaps ironically, because the API's designers wanted to protect users from sites that might scam them by calling payments from multiple stored cards.
canMakePayment call can only be used once by a site requesting payment: a second call raises the exception
NotAllowedError: Not allowed to check whether can make payment.
The slip-up is that when Olejnik tested this in Chrome, he found it didn't work properly in Incognito mode. If a user had stored values for MasterCard and Visa, for example, the second call to the API returns a “true” value for both cards.
It would, he wrote, behave like that for all the cards a user stored, turning “a fingerprinting vector into an information leak!”.
Olejnik noted that he reported the issue to the Chrome team here. ®