Skip to content
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

Allow to override issues with payment-requests (failed download/expired or wrong certificate) #268

Open
fortran77 opened this issue May 21, 2016 · 30 comments

Comments

@fortran77
Copy link

I went to the URL https://www.humblebundle.com/books/open-road-mystery-novels with the Google Chrome web browser and opted to pay using bitcoins. I saw a screen (see attached example screenshot) generated by Coinbase.com. When I scanned the QR code with the Mycelium wallet (version 2.7.4 on a Nexus 9 running Android 6.0.1), it gave me error messages: under "Merchant" I saw the error message "invalid certificate", and under "Signature" I saw the error message "invalid signature". There was no choice on the screen other than Cancel.

When I scanned the same QR code with the Coinomi wallet (version 1.6.2), it correctly interpreted it and derived from it the payment amount and the bitcoin address to send it to.

screenshot 2016-05-20 at 16 39 44

@Giszmo
Copy link
Contributor

Giszmo commented May 21, 2016

Did you try scanning it various times with Mycelium, too? The code contains:

bitcoin:1CzPvrKrFZgwM2nXTM1yChubjfZfzbrDh6?amount=0.033735&r=https://www.coinbase.com/r/573f9f75f9702e5891000409 which means "go to https://www.coinbase.com/r/573f9f75f9702e5891000409 and get further instructions. If you have no clue what the r= parameter is, use the provided bitcoin address and amount!".

Mycelium does understand the r= parameter and according to the BIP ignores the address part. If the BIP72 payment request fails though, the BIP sais:

If a PaymentRequest cannot be obtained (perhaps the server is unavailable), then the customer should be informed that the merchant's payment processing system is unavailable. In the case of an HTTP request, status codes which are neither success nor error (such as redirect) should be handled as outlined in RFC 2616.

It would be helpful to know what exactly was served.

@fortran77
Copy link
Author

I did try the same checkout procedure about three or four times, and got the same error each time. Finally I used Coinomi and it worked.

Some time later, after I filed this issue, I scanned the QR code with a bar code reader, and went to the r= URL with Google Chrome, and got the error message "Invalid Accept header". I just got the same response again.

Assuming that Coinbase.com was presenting invalid instructions at the r= URL, we still have the issue that Mycelium didn't work but Coinomi did. So from the user's point of view something must be wrong with Mycelium. There should be some work-around. For example there could be a manual override letting the user ignore the URL and use the provided payment address.

@fortran77
Copy link
Author

I did a little detective work as follows.

Did the same checkout, and got the same error messages from Mycelium.

Scanned the QR code with a bar code app, and extracted the r= URL.

Visited that URL with wget. The command-line was:

    wget --header='Accept: application/bitcoin-paymentrequest' 'https://www.coinbase.com/r/5741140c7d666c01270002b4'

This resulted in wget downloading a binary file named '5741140c7d666c01270002b4'. According to 'strings -a', this binary file contains numerous references to SSL certificates, and some payment information.

I'm uploading this file in case the Mycelium developers wish to analyze it. I did not enter any private information when performing the previous steps, so there should be no private information in this uploaded file.

5741140c7d666c01270002b4.zip

@fortran77
Copy link
Author

I just realized that you might need the headers too. This time I used the command:

wget --server-response --header='Accept: application/bitcoin-paymentrequest' 'https://www.coinbase.com/r/5741140c7d666c01270002b4'

Headers are below. The downloaded file was identical to the previous one.

--2016-05-21 19:48:45--  https://www.coinbase.com/r/5741140c7d666c01270002b4
Resolving www.coinbase.com (www.coinbase.com)... 104.16.9.251, 104.16.8.251
Connecting to www.coinbase.com (www.coinbase.com)|104.16.9.251|:443... connected.
HTTP request sent, awaiting response...
  HTTP/1.1 200 OK
  Date: Sun, 22 May 2016 02:48:48 GMT
  Content-Type: application/bitcoin-paymentrequest
  Transfer-Encoding: chunked
  Connection: keep-alive
  Set-Cookie: __cfduid=dece0aac2dee8ce6dad067722b451ed6c1463885327; expires=Mon, 22-May-17 02:48:47 GMT; path=/; domain=.coinbase.com; HttpOnly
  Cache-Control: private, no-cache, no-store, must-revalidate
  Content-Disposition: attachment
  Content-Security-Policy: default-src 'self' https://www.coinbase.com; connect-src 'self' https://www.coinbase.com https://api.coinbase.com https://*.olark.com https://api.mixpanel.com https://*.online-metrix.net https://api.cloudinary.com https://www.fullstory.com wss://ws.coinbase.com; font-src 'self' https://www.coinbase.com https://fonts.gstatic.com; frame-src 'self' https://www.coinbase.com https://*.olark.com https://*.wpstn.com https://*.online-metrix.net https://*.siftscience.com https://netverify.com https://www.youtube.com https://player.vimeo.com; img-src 'self' https://www.coinbase.com https://images.coinbase.com https://*.olark.com https://exceptions.coinbase.com https://coinbase-uploads.s3.amazonaws.com https://i2.wp.com https://secure.gravatar.com https://secure.etrust.org https://ssl.google-analytics.com https://www.google.com https://*.siftscience.com https://api.mixpanel.com https://*.online-metrix.net https://*.newrelic.com https://maps.gstatic.com https://res.cloudinary.com data:; media-src 'self' https://www.coinbase.com https://*.olark.com; object-src 'self' data: https://www.coinbase.com https://cdn.siftscience.com https://*.online-metrix.net https://www.gstatic.com; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://www.coinbase.com https://*.olark.com https://cdn.siftscience.com https://*.newrelic.com https://bam.nr-data.net https://*.google-analytics.com https://www.google.com https://www.gstatic.com https://www.youtube.com https://*.ytimg.com https://*.online-metrix.net https://chart.googleapis.com https://maps.googleapis.com https://maps.gstatic.com https://netverify.com https://ajax.cloudflare.com https://www.fullstory.com https://code.jquery.com; style-src 'self' 'unsafe-inline' https://www.coinbase.com https://*.olark.com "\\ "https://*.googleapis.com https://*.google.com; report-uri /csp-report;
  Content-Transfer-Encoding: binary
  ETag: W/"d9f75a4577692c78a746747e8871122f"
  Expires: Sat, 01 Jan 2000 00:00:00 GMT
  Pragma: no-cache
  Public-Key-Pins: max-age=5184000; pin-sha256="r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E="; pin-sha256="WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18="; pin-sha256="JbQbUG5JMJUoI6brnx0x3vZF6jilxsapbXGVfjhN8Fg="
  Set-Cookie: _coinbase=L2NBRXlobG1hQmZTY0x6V0xJT1hYTzNNRXQwQTAvNEVSSkJtNXJTeWZ4cWUvcWdoVTBRZ05mVlY2UCtuMWZzcTl1b2h0US95a2FoK05Rb0VVTzF5SHlCemwyODVJMU94NkhRVjFWYnJqVzZPRVByUW9Dc21oK1Z0WkxaK0pWOW14bmhra0pLZVZaQlZkRDg4RW1FV1BnPT0tLWJTUzQ5TDRNQkxiQkR6SGQvb3hFUUE9PQ%3D%3D--17489069fefe0838cb2e130dbef00afef6d332f4; path=/; secure; HttpOnly
  Strict-Transport-Security: max-age=15552000; includeSubDomains; preload
  Vary: Accept-Encoding
  X-Content-Type-Options: nosniff
  X-Download-Options: noopen
  X-Frame-Options: SAMEORIGIN
  X-Permitted-Cross-Domain-Policies: none
  X-Powered-By: Proof-of-Work
  X-Request-Id: 3b7d2bef-014c-43d6-a859-8d7a9919d492
  X-XSS-Protection: 1; mode=block
  Server: cloudflare-nginx
  CF-RAY: 2a6cf380aae80daf-SJC
Length: unspecified [application/bitcoin-paymentrequest]
Saving to: ‘5741140c7d666c01270002b4.1’

    [ <=>                                                                                                                                                                      ] 3,213       --.-K/s   in 0s      

2016-05-21 19:48:47 (6.19 MB/s) - ‘5741140c7d666c01270002b4.1’ saved [3213]

@Giszmo
Copy link
Contributor

Giszmo commented May 22, 2016

Thank you for your detailed report. Last thing I would be interested in is if the other wallet actually did a use the r= portion or if it fell back to using the address and amount from the QR (upon error or immediately.)

Anyway, we will have to investigate this further.

@fortran77
Copy link
Author

fortran77 commented May 22, 2016

The other wallet, which I used to successfully make the payment, was Coinomi. It did not report any error or warning; but immediately gave me a confirmation screen with the recipient's bitcoin address, the payment amount, and a miner's fee, already filled in, ready for me to push Send.

Their website (at https://coinomi.com/) does not seem to mention BIP72 anywhere and neither does the github source repository (at https://github.com/Coinomi/coinomi-android). So I would guess that Coinomi used the payment information directly and did not query the r= URL.

Edit: Bitpay has a table (at https://bitpay.com/docs/wallets) that says that Coinomi does not provide Payment Protocol Support, by which they mean BIP70, BIP71, BIP72 and BIP73.

@Giszmo
Copy link
Contributor

Giszmo commented May 22, 2016

so it working with Coinomi doesn't even hint at the url working. We have to dig into the stored response, although it's not sure that response is what the wallet failed with. Thanks for the information anyway. We definitely need to improve the error reporting. Maybe some optional "if you think it was fine, you can send us the issue" button.

@fortran77
Copy link
Author

I went to the same URL (https://www.humblebundle.com/books/open-road-mystery-novels) and tested the checkout process again. Mycelium again gave me the same error message. But the Copay wallet, which does implement BIP72, interpreted the QR code correctly and offered to let me send a payment as expected.

Depending on your degree of motivation, you can do the test yourself. Simply enter any test email address (e.g., testemail@example.com) and click on the Bitcoin button. That will give you the page with the QR code. No login is required, and no transaction will occur unless you actually send a payment.

@DanielWeigl
Copy link
Contributor

DanielWeigl commented May 23, 2016

If i try to parse your uploaded PR (5741140c7d666c01270002b4.zip) i get following result from androids own verification method:

Could not validate certificate: Certificate expired at Fri May 13 14:00:00 GMT+02:00 2016 (compared to Mon May 23 08:30:48 GMT+02:00 2016)

Also the same happens if i fetch a new payment request from coinbase (via humblebundle)

Ill contact coinbase and try to find out more, if its a problem in our cert parsing or they simply missed to update their certs.

Update: just tried it with Schildbach, same result. Their cert is expired. But that makes one wonder that they did not get any bug reports for the last 10 days....

Update2: https://community.coinbase.com/t/certificate-for-bip77-payment-request-is-expired/11060

@DanielWeigl
Copy link
Contributor

DanielWeigl commented May 23, 2016

BitcoinCore parses the payment request and allows the user to pay to it. It only marks it with a yellow background instead a green one. And only the tool-tip says "This is an unauthenticated payment request."

screenshot

@dooglus
Copy link

dooglus commented Jun 6, 2016

I just tried buying Reddit Gold with Bitcoin. It gave me a QR code to scan. I used Mycelium to scan the code and got the same error.

Here's the coinbase request for payment:

screenshot - 060616 - 01 02 33 am

and here's the result in Mycelium:

screenshot_20160606-010207

The QR code decodes to bitcoin:1Mi9eSv8MCwUBra4B5VRXNWd9HBJrotkii?amount=0.051373&r=https://www.coinbase.com/r/57552d90c4025871ad001577.

Can it really be that Coinbase have been using an expired certificate for nearly a month without fixing it?

@dannyellis-zz
Copy link

It almost seems like it. Sad that they haven't even responded to the guy's thread on their forum either.

I had to move some coins over to a different wallet that seems to work on android. Coinomi. I dont like it nearly as much as mycelium but I was running out of time on a subscription

@dooglus
Copy link

dooglus commented Jun 7, 2016

I worked around it by scanning the QR code, emailing the URL to myself from the phone to my laptop, removing the &r=... bit of the URL, encoding a new QR code, and scanning that on the phone.

Kind of annoying, but I couldn't think of a better way to do it. I didn't want to be manually typing the address or the amount on the phone.

@dooglus
Copy link

dooglus commented Jun 7, 2016

Maybe Mycelium could offer to use the payment request anyway, even if the certificate has expired. Or offer to use the amount and address from the URL and ignore any bad payment requests.

@dooglus
Copy link

dooglus commented Jun 7, 2016

@dannyellis

Sad that they haven't even responded to the guy's thread on their forum either

I just noticed they replied to my tweet at them yesterday:

"@dooglus sorry about that :( We're working to fix it asap" -- https://twitter.com/dooglus/status/739734929723031552

screenshot - 060616 - 10 53 27 pm

@Giszmo
Copy link
Contributor

Giszmo commented Jun 20, 2016

So according to twitter, the certificate is updated.
Mycelium works as per BIP72 and I find Bitcoin Core's approach questionable, to just ignore an invalid certificate. If payment requests are used, recipient should use them correctly or they defeat their purpose, if ignoring certificates is at no cost to the user/merchant.

Better safe than sorry. Closing.

@Giszmo Giszmo closed this as completed Jun 20, 2016
@dooglus
Copy link

dooglus commented Jun 20, 2016

Sorry, I forgot to update this issue. The CoinBase cert. does appear to be working now according to my tests.

@Giszmo
Copy link
Contributor

Giszmo commented Jun 20, 2016

Didn't close it lightly, as users will hate us for being the only wallet that doesn't let them pay, with even Core being being "less paranoid" but I guess it's the right thing to do. At first the error message was not ok but with that fixed, it's fair to not just default to the next best thing.

@dooglus
Copy link

dooglus commented Jun 20, 2016

It would still be preferable to allow the user to ignore the payment request part completely and just use the address and amount directly from the URL.

That's what they're going to do anyway, but it's a pain in the ass to have to copy the address character by character from the computer to the Android device when the information is already in the QR code they scanned.

@Giszmo
Copy link
Contributor

Giszmo commented Jun 20, 2016

well, it's not that dramatic if you know how. Just use any qr-code scanner, copy the value, paste it to the browser, edit the url, open the url. It will offer Mycelium.

skipbip72

Yes, being more strict than BitcoinCore in complying with a BIP was annoying in this case but it really was Coinbase's fault.

@Rassah
Copy link

Rassah commented Jun 20, 2016

Isn't the issue that without the certificate a MITM attacker can just change the address in the URL?

@Giszmo
Copy link
Contributor

Giszmo commented Jun 20, 2016

Isn't the issue that without the certificate a MITM attacker can just change the address in the URL?

To be fair, a MITM attacker could just remove the r= part and change the Bitcoin address. Only well experienced users would suspect something with the missing extra information.

Bitcoin Core's approach is not totally wrong but it defeats the purpose of checking the certificate if the user doesn't get clearly warned about things looking fishy.

@fortran77
Copy link
Author

fortran77 commented Jun 20, 2016

These things go in cycles. We always begin with aspirations for a secure universe. Then we realize we need compromises, because security is never absolute, website owners are not always clueful, and users are sometimes impatient to get something done even if there is some risk.

In the mid nineties, after SSL began to become popular, visiting a website with an invalid (usually expired) SSL certificate was an exercise in frustration. Early web browsers (Netscape Navigator to begin with, then Microsoft's IE, then Opera, then others) refused to let the user easily override a website's broken SSL.

Web browser makers eventually realized that an easy manual override was essential to allow normal use of websites administered by sloppy web designers. And they made it quite a bit easier for even naive users to get past the warnings.

Today, we are going through a similar cycle with the increasing use of HSTS, which essentially tells the web browser to disallow any manual override no matter how careless the web designer and no matter how frustrated the user. So, as we see increasing use of Let's Encrypt SSL certificates (with a 3-month lifetime), and more and more poorly-administered websites that use both HSTS and an expired Let's Encrypt SSL certificate, there will be more and more frustrated users who can't visit a website even though there's nothing there that is so valuable that anybody would bother to mount a man-in-the-middle attack.

The same will happen with $15 payments that cannot be made because the bitcoin wallet is too strict and the website administrator can't be bothered to update the SSL certificate. After an initial period of user frustration, we will all come to some compromise, where the user can press a "proceed anyway, I know the SSL has been broken for a month, what do you expect, it's Coinbase after all" button.

@dooglus
Copy link

dooglus commented Jun 20, 2016

After an initial period of user frustration, we will all come to some compromise, where the user can press a "proceed anyway, I know the SSL has been broken for a month, what do you expect, it's Coinbase after all" button

That's the button I was hoping for. But maybe the period of user frustration hasn't been long enough yet.

@Giszmo Giszmo changed the title Mycelium wallet rejects payment request from Coinbase but Coinomi can process it Allow to override issues with payment-requests (failed download/expired or wrong certificate) Jun 21, 2016
@Giszmo Giszmo reopened this Jun 21, 2016
@Rassah
Copy link

Rassah commented Jun 21, 2016

I've never seen an expired certificate from PayPal, Bank of America, Discover, or any other serious finance business.

@dooglus
Copy link

dooglus commented Jun 21, 2016

OK, so we can maybe conclude that CoinBase isn't a serious finance business. That probably won't come as much of a shock to anyone.

The question is what we should be doing in the event that someone sends you a payment request with an expired certificate. I would argue that we should do the same thing a web browser does when an SSL site sends you an invalid certificate: show a big warning explaining what went wrong, and allow the user to continue despite the warning.

@Rassah
Copy link

Rassah commented Jun 21, 2016

Who is liable if the transaction is sent to a wrong address?

@fortran77
Copy link
Author

Liability could be minimized by making it very hard or impossible to override an invalid SSL certificate above some payment threshold. The threshold could be hard-coded by the Mycelium developers, or it might be user-settable.

Aside: Talking about payment thresholds, these should also exist to protect against user error. The Internet is full of complaints from people who accidentally sent too many bitcoins or made the miner's fee too big. In conventional banking, no payment is instantaneous, so there is time to catch errors. Or they can be reversed easily. The bitcoin world should compensate for its quicker and more final payments by including better heuristics to detect errors before they become final.

@Giszmo
Copy link
Contributor

Giszmo commented Jun 21, 2016

@fortran77 : The Mycelium Wallet is open source software and provided as is. Implementing a threshold that any specific distributor would be happy to cover in case of malicious certificates would set a dangerous precedent.

The other suggestion is covered by #188. Please keep the issues separated.

@dooglus
Copy link

dooglus commented Jun 24, 2016

@fortran "Talking about payment thresholds, these should also exist to protect against user error" << I wouldn't be in favour of limits on how much can be sent. I've made many payments of 500 BTC and more from Mycelium. Crippling it to disallow large payments would make it significantly less useful to me. Maybe a setting would be useful so users could set their own threshold above which a warning would be issued, but having a limit which the user cannot override would make things worse.

@Rassah the user is liable for all the transactions he makes. Mycelium should issue a clear warning when a payment request is invalid, and make it clear that the user proceeds at their own risk.

Giszmo pushed a commit that referenced this issue May 24, 2018
…mydfs

#955 Unpublish Apex and MyDFS on specific dates
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants