user2233709
user2233709

Reputation: 203

Firefox would not perform a CORS request to http://127.0.0.1 from page served over https…

I need to make a web app communicate with a program running on an end-user’s computer.

The web app requires authentication and is served over https.

The program running on the end-user’s computer includes a http server that listen on 127.0.0.1:12345.

To send data from the web app to the program, I perform a PUT request, using the Fetch API. It has to be a CORS request since PUT is not allowed for non-CORS request. (A POST request would be allowed for a non-CORS request, but I would not be able to specify the right Content-Type…)

All this works fine with Chromium (version 73), but fails with Firefox (tried with versions 60 and 67, no request sent at all, not even the CORS-preflight request).

After some investigation, it seems that it works fine when the page is served over http, but not when it is served over https. As I understand it, it seems to be related to the specification that states that:

[…] user agents are allowed to terminate the algorithm and not make a request. This could be done because e.g.:

  • […]
  • https to http is not allowed.

Is there any way to work around this and allow Firefox to perform CORS requests to 127.0.0.1 over http, even from a https page?

As I understand it, since the request is sent to localhost (127.0.0.1), http is not much less secure than https. Running the web app over http rather than https would work, but it is not an option. Having a TLS certificate, for localhost, installed on the end-user’s computer, to run a https server in the program that runs on the end-user’s computer, is not really an option either…

EDIT: The web app tries to access http://127.0.0.1/12345, not http://localhost:12345 as I wrote before.

According to the note at the end of the MDN Web Doc about mixed content, Firefox should allow mixed content from http://127.0.0.1.

Upvotes: 1

Views: 530

Answers (1)

Eric Wong
Eric Wong

Reputation: 1463

I think there is no straight-forward way to do this, i.e. forcibly making page loaded in HTTPS to fetch content from HTTP server. Mixed content is definitely a no-go and Firefox's implementation is somewhat "more secure". There are some alternatives I can think of though.

First running HTTPS server is not all that "not an option", you do not have to create CA and install TLS and stuff. You can just buy a real domain, myapp.com, setup a subdomain like loopback.myapp.com, make it resolve to 127.0.0.1 (CloudFlare let you do DNS for free), buy a real certificate for that subdomain, distribute the private and public key in that local app bundle and run a HTTPS server.*

Another approach is to extend your local app to act as a proxy server which serves at say localhost:8000 and transparently communicate with your remote web app through HTTPS. But of course that relies on your web app not hardcoding the domain name.

* This can theoretically opens up security hole: malicious user can perform DNS spoofing and make victim's loopback.myapp.com resolves to attacker's machine, and since everyone has the key, attacker will be able to decrypt it as well. You can mitigate this by hardcoding loopback.myapp.com to 127.0.0.1 in /etc/hosts

Upvotes: 1

Related Questions