TCP connection made over port 80 with HTTPS only enabled
Categories
(Core :: DOM: Security, defect, P2)
Tracking
()
Tracking | Status | |
---|---|---|
firefox96 | --- | fixed |
People
(Reporter: bugsgalore, Assigned: ckerschb)
References
(Blocks 2 open bugs)
Details
(Keywords: nightly-community, parity-chrome, privacy, Whiteboard: [domsecurity-active])
Attachments
(3 files)
Enable HTTPS only mode.
Write example.com in the address bar and hit enter.
Observe an unexpected TCP connection made to port 80 in addition to the secure connection.
Assignee | ||
Comment 1•3 years ago
|
||
Thanks for reporting, though that is expected behavior to avoid potentially long timeouts. As counter-intuitive as that might sound, here is the reasoning:
- HTTPS-Only tries to upgrade the top-level request from
http
tohttps
. - If, after 3 seconds, no response has been received, Firefox sends an
http
background request (stripping path, cookies, query information, etc to avoid potential privacy leaks). - If the
http
background request receives a signal faster then the upgradedhttps
request, then that's a strong signal that thehttps
request will result in a time-out and we show the exception page.
You can flip the pref dom.security.https_only_mode_send_http_background_request
to false
which would then not send the background request, with the downside that you might run into 90 second timeouts.
If you want all the exact details you can look at:
- Our Blogpost, providing insights: https://blog.mozilla.org/attack-and-defense/2021/03/10/insights-into-https-only-mode/
- Our Academic Paper providing deep insights: https://blog.mozilla.org/attack-and-defense/files/2021/03/httpsonly_paper.pdf
Page load is finished in less than 500ms so the 3 second timeout does not apply here.
I have set dom.security.https_only_mode_send_http_background_request to false, but as I said the page loads in less than 500ms so it does not apply here anyway.
Chrome with the exact same repro steps maintains complete radio silence over port 80 and AFAIK, Chrome does not have any kind of HTTPS only mode, or at least I have not enabled any extra security features there.
Assignee | ||
Comment 3•3 years ago
|
||
What is the http
URL (port 80) you are observing?
You can observe that by opening the Hamburger Menu
on the right hand side -> More tools
-> Browser console
.
I dont see anything in the Browser Console, but you can see the connection made to port 80 in about:networking and observe the TCP connection being made to the server IP to port 80 with a tool like Wireshark.
On Windows you can use built-in pktmon with filter "pktmon filter add -i 93.184.216.34 -p 80" and "pktmon start -c -m real-time" in Powershell and type example.com in the addres bar and hit enter.
Do note that the connection needs to be "upgraded to https" i.e. when typing the URL the "visit" field autofill below needs to have "http" instead of "https" as protocol (the default) and the lock icon needs to indicate "upgraded to https" after entering the site.
Glancing through about:networking I can also sometimes see completely unrelated non-SSL port 80 connections to some hostnames I have not visited during my browsing session. Maybe this is some weird "pre-connection" feature arbitrarily picking hosts from my history for "pre-connecting"? But again these "pre-connections" are non-SSL and over port 80 which I would expect should not happen with HTTPS-only enabled.
Looks like Chrome does default to HTTPS nowadays, however Firefox makes non-SSL connections over port 80 even with HTTPS only enabled:
https://www.zdnet.com/article/chrome-will-soon-try-https-first-when-you-type-an-incomplete-url/
Comment 9•3 years ago
|
||
Looks like Chrome does default to HTTPS nowadays,
I wasn't able to get that to work in my copy of Chrome (might have tweaked some setting and forgot?) but that article describes assuming "https://" instead of "http://" when people don't specify in the omnibar. That's not quite what we're doing since ours also applies to links, navigations and subresources. Chrome is experimenting with something much more like what we're doing, described in a blog post a few weeks ago: https://blog.chromium.org/2021/07/increasing-https-adoption.html (we chat: both security teams have the same end goal, and share notes on what nudges and interventions are working and what problems we run into).
It would really really help if you supplied data about the specific sites that you see in the connections, as Christoph asked in comment 3. What I tried:
[Using Firefox Release (91.0.1), default configuration, no addons]
- enable HTTPS only
- Re-start the browser to ensure no contamination of results from older connections
- On the initial--and only--tab (showing all the pocket stories) load the
about:networking
page - check out the list. I see port 80 connections to
detectportal.firefox.com
and several OCSP servers. - in the same tab, go to "example.com" (without specifying the scheme)
- Go back to about:networking, hit the refresh button, see what's different
The only additional port 80 connection I see is "example.com" itself. It looks like we make that request right away.
If I disable the pref dom.security.https_only_mode_send_http_background_request
(as you said you also did in comment 2) then I do not see a port 80 connection to "example.com" when I do the above steps.
Note: r3.o.lencr.org
is an OCSP server. They don't always have OCSP in the name.
The presence of addons, a different home page, or browsing around before the test will affect what shows up in the first look at about:networking. Addons or other loaded tabs might make additional connections between step 3 and step 6 that contaminate the results. If you're unlucky on timing you might see additional mozilla connections between steps 3 and 6 for various update checks, or to the Google safebrowsing service.
Reporter | ||
Comment 10•3 years ago
|
||
Ok, this bug is getting quite convoluted, just now I noticed in about:networking that I have connections to detectportal.firefox.com there from during this browsing session even though I have disabled the service from about:config... That's just great.
Anyway, to the original issue at hand:
- Install Firefox fresh. Enable HTTPS only mode and set dom.security.https_only_mode_send_http_background_request to false. Restart Firefox.
- Write example.com in the address bar (the autofill is http://) and hit enter
- Get connection upgraded to HTTPS
- However there still is a TCP connection made over port 80
- This also happens on any http:// link you press on a website that results in an upgrade to HTTPS.
With the same steps on Chrome (write example.com in the address bar and hit enter), the connection just gets upgraded to HTTPS and there is no connection made over port 80.
I have attached screenshots demonstrating this from Wireshark.
Reporter | ||
Comment 11•3 years ago
|
||
Reporter | ||
Comment 12•3 years ago
|
||
Comment 13•3 years ago
|
||
I noticed in about:networking that I have connections to detectportal.firefox.com there from during this browsing session even though I have disabled the service from about:config...
There are three prefs that contain links to detectportal.firefox.com -- you'll need to change them all. That's not relevant to this bug though since those connections can be disregarded wrt your main point.
Comment 14•3 years ago
|
||
It would really help to get a log of the connections from the browser console (found in the tools menu), which will contain the hostnames Firefox thinks it's trying to reach. the IP address in your picture means nothing to me and doesn't seem to equate to any mozilla domain.
Is this connection at startup? (that's a totally different team)
Is this a connection that happens related to loading a web page?
Do you have any addons installed that might be making connections?
Reporter | ||
Comment 15•3 years ago
|
||
Comment 10 has the repro steps. (I see Firefox uses "detectportal" also for some kind of ipv4 and ipv6 connectivity testing in addition to portal detection so that has been cleared up I guess so ignore the first sentence)
The IP (93.184.216.34) is the A record of example.com, the Ip address Firefox will make a connection to when visiting example.com.
There should be no reason for Firefox to open a TCP connection to the web server (example.com 93.184.216.34) over port 80 that is meant for unencrypted connections when I have HTTPS only enabled. There should only be an encrypted connection established over port 443.
This happens on any domain you visit that gets a connection upgraded to HTTPS, whether through writing the domain name in the address bar or clicking a link.
Updated•3 years ago
|
Reporter | ||
Comment 16•3 years ago
|
||
Here is another major profile site easy to reproduce this with: http://europa.eu
Writing http://europa.eu in the address bar and pressing enter to visit the site creates a superfluous TCP connection to the site over port 80 as confirmed with a packet sniffer in addition to the HTTPS-upgraded connection over port 443. Just like in the screenshot demonstrating this before.
Browser console shows "HTTPS-Only Mode: Upgrading insecure request “http://europa.eu/” to use “https”."
about:networking shows the superfluous connection as
"host europa.eu port 80 HTTP <= 1.1 ssl false"
in addition to the correct intended connection:
"host europa.eu port 443 HTTP <= 1.1 ssl true"
So, to summarize, some bug in Firefox is causing the browser to open a TCP connection that essentially does nothing over port 80 which is intended for unencrypted connections, in addition to the intended secure connection over port 443.
Chrome does not do this, instead maintaining radio silence over port 80.
Assignee | ||
Comment 17•3 years ago
|
||
Dragana, Valentin, so now that I re-evaluate that Bug it's concerning after all that there is a superfluous TCP connection on port 80 when operating in https-only or https-first mode.
I would have thought that no connection attempts happen before we do nsHTTPSOnlyUtils::ShouldUpgradeRequest
. Are we doing any kind of preflight, prefetch or something there like in Necko?
Do you know anything about that?
Assignee | ||
Updated•3 years ago
|
Comment 18•3 years ago
|
||
There is also the predictor prefetch, but that is only enabled on nightly, so it's probably not to blame here.
NS_ShouldSecureUpgrade is called in nsHttpChannel::OnBeforeConnect() - when true we we call HandleAsyncRedirectChannelToHttps
SpeculativeConnect is called in nsHttpChannel::ConnectOnTailUnblock(): OnBeforeConnect -> ContinueOnBeforeConnect -> Connect -> ConnectOnTailUnblock() - so only when we shouldn't upgrade.
I think the cause here is the SpeculativeConnect triggered by the URLBar here
That's controlled by the browser.urlbar.speculativeConnect.enabled
pref. If that turns out to be the reason for this, we might want to consider making it HTTPS-only aware.
Assignee | ||
Comment 19•3 years ago
|
||
Thanks Valentin. So it seems our SpeculativeConnect
mechanism is not aware of https-first
- I'll take another look at this.
Assignee | ||
Comment 20•3 years ago
|
||
Updated•3 years ago
|
Comment 21•3 years ago
|
||
Comment 22•3 years ago
|
||
Backed out changeset fb595abd6511 (Bug 1724080) for causing failures in browser_mixed_content_console.js CLOSED TREE
Log: https://treeherder.mozilla.org/logviewer?job_id=359550200&repo=autoland&lineNumber=3312
[task 2021-11-29T12:03:43.158Z] 12:03:43 INFO - TEST-START | dom/security/test/https-first/browser_mixed_content_console.js
[task 2021-11-29T12:03:43.218Z] 12:03:43 INFO - TEST-INFO | started process screentopng
[task 2021-11-29T12:03:43.702Z] 12:03:43 INFO - TEST-INFO | screentopng: exit 0
[task 2021-11-29T12:03:43.703Z] 12:03:43 INFO - Buffered messages logged at 12:03:43
[task 2021-11-29T12:03:43.703Z] 12:03:43 INFO - Entering test bound
[task 2021-11-29T12:03:43.703Z] 12:03:43 INFO - Buffered messages finished
[task 2021-11-29T12:03:43.703Z] 12:03:43 INFO - TEST-UNEXPECTED-FAIL | dom/security/test/https-first/browser_mixed_content_console.js | request got upgraded -
[task 2021-11-29T12:03:43.703Z] 12:03:43 INFO - Stack trace:
[task 2021-11-29T12:03:43.703Z] 12:03:43 INFO - chrome://mochikit/content/browser-test.js:test_ok:1336
[task 2021-11-29T12:03:43.704Z] 12:03:43 INFO - chrome://mochitests/content/browser/dom/security/test/https-first/browser_mixed_content_console.js:on_console_message:38
And some TV failures: https://treeherder.mozilla.org/logviewer?job_id=359554309&repo=autoland&lineNumber=3370
Backout: https://hg.mozilla.org/integration/autoland/rev/32aced2e95571e06c4aa147a093a3682d739bfc5
Assignee | ||
Comment 23•3 years ago
|
||
(In reply to Noemi Erli[:noemi_erli] from comment #22)
Backed out changeset fb595abd6511 (Bug 1724080) for causing failures in browser_mixed_content_console.js CLOSED TREE
Thanks, looking ...
Assignee | ||
Comment 24•3 years ago
|
||
(In reply to Christoph Kerschbaumer [:ckerschb] from comment #23)
(In reply to Noemi Erli[:noemi_erli] from comment #22)
Backed out changeset fb595abd6511 (Bug 1724080) for causing failures in browser_mixed_content_console.js CLOSED TREE
Thanks, looking ...
Ah, the test dom/security/test/https-first/browser_mixed_content_console.js
was relying on a single
https-first
console message, but that statement does not hold true anymore since we are also logging a message for the speculative connection
upgrade. I slightly adapted that test and now everything works as expected.
Comment 25•3 years ago
|
||
Comment 26•3 years ago
|
||
bugherder |
Description
•