mozilla / standards-positions

https://mozilla.github.io/standards-positions/
Mozilla Public License 2.0
635 stars 69 forks source link

Cryptocurrency support with Payment Request API #78

Closed marcoscaceres closed 6 years ago

marcoscaceres commented 6 years ago

Request for Mozilla Position on an Emerging Web Specification

Other information

The Payment Request API currently only checks that monetary values passed into it adhere to the ISO4217 currency format: ASCII 3-alpha (e.g., "USD", "EUR", etc.). However, the spec doesn't ask the browser to check if those are "real" (fiat) currencies - which would be possible by checking against ISO4217 itself (maintained and updated by ISO).

There is a proverbial elephant in the room around cryptocurrencies, such as "BTC", which, although they conform to the ISO4217 "currency format", may or may not be "real" currencies.

Recently, Facebook, Google, and soon possibly Twitter, have banned advertising crypto currencies in their platform due to high levels of fraud.

When using the Payment Request API, I personally fear that by not checking if a currency is registered with ISO (as a "real" currency), we might subject Firefox users to fraud. For instance, a website might insist that you can only buy things with a particular crypto currency (or similar scams already seen).

What I'd like to propose is that, at a minimum, all currencies (including cryptocurrencies) be first blessed by ISO before they can be used with the Payment Request API. Coincidently, ISO is exploring the possibility of formally registering cryptocurrencies. This would be a minimum level of due diligence that would be required to use a currency.

Opinions? Is this something we (Mozilla) should push for in the spec (e.g., "if it's not in ISO4227, throw a RangeError." )? Or maybe just an assurance we implement into Firefox?

Opinions would be appreciated.

dbaron commented 6 years ago

What's the licensing of the ISO4217 currency list?

marcoscaceres commented 6 years ago

... Currency Codes tables (XML and XLS format) of the ISO 4217 International Standard may be used freely. SIX assumes no responsibility for the completeness of this information, nor for any damages from actions taken based on this information. SIX reserves the express right to change or delete this information from its website at any time.

https://www.currency-iso.org/en/services/legal/terms-of-use.html

annevk commented 6 years ago

Kinda makes it sound like it would be good for someone to host a copy of that list with non-deletion guarantees.

hsivonen commented 6 years ago

My initial thoughts (without conclusions!) are:

bzbarsky commented 6 years ago

It's always interesting to compare ISO4217 to https://en.wikipedia.org/wiki/List_of_states_with_limited_recognition

Of the places that are on that list but not in ISO4217, I see (all according to wikipedia, so take with a grain of salt as needed):

Also of interest are the lists at https://en.wikipedia.org/wiki/ISO_4217#Currencies_without_ISO_4217_currency_codes which includes some of the above and some currencies that do not correspond to independent nations at all. Though most of the latter are pegged to recognized currencies anyway, so for online transaction purposes may not matter.

Also also of interest is https://en.wikipedia.org/wiki/ISO_4217#Unofficial_currency_codes which has some overlap with all the above and some distinct bits (e.g. NIS vs ILS and CNH/CNT vs CNY).

stpeter commented 6 years ago

This seems appropriately opinionated regarding user safety. If a merchant wants to use a currency not recognized by ISO, they don't have to call the Web Payments API.

adamroach commented 6 years ago

I think we need to take a step back and be clear about the threat model here.

When the Payment API is invoked, the only way it's not going to fail is if the browser itself or some registered payment handler is capable of dealing with the currency being requested. So, from a webpage perspective, asking for random, unassigned currencies is generally going to simply fail.

Now, in the specific case of cryptocurrencies, the only way I believe this can work is that the user installs some kind of cryptocurrency payment handler (which will be linked to a trusted service that has access to a user's wallet or some other financial instrument that can fund a wallet); then visits a webpage that requests money in a form such a payment handler can provide; and then works with the payment handler's own authentication to okay the transaction.

Given the above, can someone walk through the steps that would be used to mount an attack that is different than an attack involving a fiat currency?

annevk commented 6 years ago

I think there's also a UX consideration. Do we want to support arbitrary strings (or are there nonetheless some imposed limits?) as currencies there?

marcoscaceres commented 6 years ago

I think there's also a UX consideration. Do we want to support arbitrary strings (or are there nonetheless some imposed limits?)

Must adhere to 3 letters, else RangeError (same as JS i18n API, hooks into validity check algorithm).

as currencies there?

Spec says to display U+00A4 ¤ CURRENCY SIGN for unknown currencies... not the best, but better than everyone's favorite �.

hsivonen commented 6 years ago

Spec says to display U+00A4 ¤ CURRENCY SIGN for unknown currencies...

Why not the three-letter code? Even for known currencies, it's bad enough that neighboring countries have different dollars.

marcoscaceres commented 6 years ago

Why not the three-letter code? Even for known currencies, it's bad enough that neighboring countries have different dollars.

We show them like this (currency-sign value currency-code): screenshot 2018-03-27 20 24 09

marcoscaceres commented 6 years ago

@annevk wrote:

Kinda makes it sound like it would be good for someone to host a copy of that list with non-deletion guarantees.

I think the currency codes are pretty stable, because so much of the worlds commerce relies on them.

@hsivonen wrote:

Is this a concern for the browser to police for methods other than basic-card?

Yeah, I would think so.

Can a credit card even be billed in a non-ISO4217 currency?

Not that I know of. However, the other motivation is for paying with credit card "point" or "miles". Although I've seen the sites that own the miles programs allow users to purchase things with points (e.g., when booking a flight through Qantas, etc.), I've personally never seen a websites allow payment with a third-party's points/miles (where these point systems are a non-ISO4217 currency system).

I've asked the working group to provide example websites that do this. Waiting to see examples.

@bzbarsky, all specs have bugs, I guess... but seriously, I we do need to consider how often ISO4217 is updated (every few years, it seems).

@adamroach, sorry, ran out of time... I'll see if can come up with a straw-person tomorrow!

adrianhopebailie commented 6 years ago

As pointed out in the issue on the WG list at https://github.com/w3c/payment-request/pull/694#issuecomment-376189807 and alluded to by @adamroach there is a conflation of issues here.

We are talking about imposing an arbitrary restriction by browsers on the data that can be exchanged, when the usefulness of a non-standard currency is actually determined by the other participants in the transaction. Personally I am very surprised this is even under discussion.

With respect, references to the banning of crypto-currency advertising suggests that not everyone on this thread actually understands this issue, the threats that are being dealt with by these platforms or the context.

Are we going to somehow prohibit the use of PR API on porn sites because large platforms have prohibited advertising by those websites or distribution of the content sold on those websites?

For instance, a website might insist that you can only buy things with a particular crypto currency (or similar scams already seen).

That is the choice of the website. The user has to a) have that currency to be able to spend it and b) should trust the website before they spend anything there anyway, whether it is crypto-currency, fiat currency or some other currency like airline miles.

Nothing stops people selling goods/services for these other currencies today so I'm not sure why browsers feel they have a mandate to be the user police in this instance?

If I want to use Bitcoin or airline miles for a transaction, I need both a payment handler that can help me to authorize that payment, a merchant that accepts payment in that currency AND there must exist a payment network, in which they both participate, that uses that currency. This is policed by the ecosystem, it not a browser concern.

What IS important for browsers to do to protect their users is to ensure that users can clearly see what they are agreeing to when selecting a payment handler for a payment request. This prevents the very obscure threat of a merchant and payment handler colluding to process a transaction in one currency when the user thinks it is being done in another (which is just as likely using two fiat currencies).

To that end I think using any symbol for unknown currencies is a mistake. I agree that the only currency indicator on the UI should be the code if no symbol is known.

hsivonen commented 6 years ago

This prevents the very obscure threat of a merchant and payment handler colluding to process a transaction in one currency when the user thinks it is being done in another (which is just as likely using two fiat currencies).

FWIW, with fiat currencies in the brick&mortar context, this isn't at all obscure, unfortunately. When traveling with an Eurozone-based credit or debit card in non-Eurozone countries in Europe (both EU and non-EEA; e.g. Poland and Switzerland), one finds that just about every brick&mortar payment terminal is configured to "helpfully" offer to charge the card in euros at a worse exchange rate than one's own credit card issuer would offer.

hsivonen commented 6 years ago

all specs have bugs, I guess... but seriously, I we do need to consider how often ISO4217 is updated (every few years, it seems).

In any case, even when everyone agrees on the legitimacy of a newly-independent country (@bzbarsky mentioned disputed regions, which are well-known source of trouble for software vendors) with its own currency, it would be really unfortunate if the new currency was locked out in practice until the long tail of browsers updates.

In any case, I think @adamroach's comment is the key thing to answer.

hsivonen commented 6 years ago

(Arguably, things that update rarely are worse for making sure that updates are actually feasible than things that never change and things that change all the time.)

marcoscaceres commented 6 years ago

Given the above, can someone walk through the steps that would be used to mount an attack that is different than an attack involving a fiat currency?

You are correct that it's not that different: like, store.com presents the cost of things in USD. The user buys something, and it's their bank that performs the currency conversion for the cost of the item.

In any case, something like:

  1. "store.com" has business arrangement with "https://cryptocoin.biz" to encourage users to buy "cryptocoin".
  2. User visits store.com, adds items to shopping chart. All prices given in cryptocoin.
  3. store.com creates a new payment request, stating that they support "https://cryptocoin.biz" and "basic-card".
  4. Using Payment Handler API, browser automatically installs "https://cryptocoin.biz" payment handler in the background (does not require authentication, permission, or user interaction to install).
  5. store.com tells user: "When you pay, try paying with cryptocoin.biz! It's the future!".
  6. User clicks "checkout" button.
  7. Browser presents user with two payment handler options ("cryptocoin.biz" and "basic-card").
  8. User selects "cryptocoin.biz" as payment handler. They are asked to create an account and buy $100 worth of cryptocoin with their credit card "to get started".
  9. User completes transaction with cryptocoin.biz, paying XCC🔮12313 cryptocoins.
  10. Cryptocoin.biz payment handler responds to store.com with tokenized response.
  11. store.com verifies token, payment completes successfully.
  12. User just bought things, and now owns a bunch of cryptocoin - might be ok, can use these maybe at other stores.

The above could also be done with, for instance, an online fiat currency wallet (e.g., toping up ones PayPal account).

So, I'm also now concluding that there is no difference. As above, one can substitute "cryptocoin" with EUR or whatever.

Given the feedback:

  1. supporting states/countries changing currencies quicker than ISO can assign them.
  2. threat model being the same irrespective of fiat/crypto currency.

    I'd be ok with then sticking with just the ISO-3-letter check, but no restrictions.

marcoscaceres commented 6 years ago

/me makes little tweaks above.

marcoscaceres commented 6 years ago

Closing, as concluding that the spec stays the same. If anyone has additional information, I'm happy to reopen. The spec will continue to work like this:

Implementations currently expect currency codes to be well-formed 3-letter codes as defined by ECMAScript’s “isWellFormedCurrencyCode” algorithm. Implementations will therefore allow the use of well-formed currency codes that are not part of ISO 4217 list (e.g., XBT, XRP etc.). If the provided code is a currency that the browser knows how to display, then implementation usually provide additional UI hints such as appropriate symbols in the user interface (e.g., "USD" is shown as "$", "GBP" is "£", and so on). When a code is can't be matched, we recommend browsers show a scarab "¤".