Closed Bug 1724080 Opened 3 years ago Closed 3 years ago

TCP connection made over port 80 with HTTPS only enabled

Categories

(Core :: DOM: Security, defect, P2)

defect

Tracking

()

RESOLVED FIXED
96 Branch
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.

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 to https.
  • 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 upgraded https request, then that's a strong signal that the https 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:

Status: UNCONFIRMED → RESOLVED
Closed: 3 years ago
Resolution: --- → INVALID

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.

Flags: needinfo?(ckerschb)
Status: RESOLVED → UNCONFIRMED
Resolution: INVALID → ---

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.

Flags: needinfo?(ckerschb) → needinfo?(bugsgalore)

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.

Flags: needinfo?(bugsgalore)

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.

Flags: needinfo?(ckerschb)

(and no they are not OCSP servers)

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/

Keywords: parity-chrome

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]

  1. enable HTTPS only
  2. Re-start the browser to ensure no contamination of results from older connections
  3. On the initial--and only--tab (showing all the pocket stories) load the about:networking page
  4. check out the list. I see port 80 connections to detectportal.firefox.com and several OCSP servers.
  5. in the same tab, go to "example.com" (without specifying the scheme)
  6. 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.

Flags: needinfo?(bugsgalore)

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:

  1. Install Firefox fresh. Enable HTTPS only mode and set dom.security.https_only_mode_send_http_background_request to false. Restart Firefox.
  2. Write example.com in the address bar (the autofill is http://) and hit enter
  3. Get connection upgraded to HTTPS
  4. However there still is a TCP connection made over port 80
  5. 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.

Flags: needinfo?(bugsgalore)
Attached image Firefox https only (deleted) —
Attached image chrome (deleted) —

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.

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?

Flags: needinfo?(bugsgalore)

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.

Flags: needinfo?(bugsgalore) → needinfo?(dveditz)
Flags: needinfo?(dveditz)

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.

Keywords: privacy

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?

Flags: needinfo?(valentin.gosu)
Flags: needinfo?(dd.mozilla)
Flags: needinfo?(ckerschb)

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.

Flags: needinfo?(valentin.gosu)
Flags: needinfo?(dd.mozilla)

Thanks Valentin. So it seems our SpeculativeConnect mechanism is not aware of https-first - I'll take another look at this.

Assignee: nobody → ckerschb
Status: UNCONFIRMED → ASSIGNED
Ever confirmed: true
Priority: -- → P2
Whiteboard: [domsecurity-active]
Attachment #9252633 - Attachment description: Bug 1724080: Have https-first rules apply to speculative connections → Bug 1724080: Have https-first and https-only rules apply to speculative connections
Pushed by mozilla@christophkerschbaumer.com: https://hg.mozilla.org/integration/autoland/rev/fb595abd6511 Have https-first and https-only rules apply to speculative connections r=kershaw

Backed out changeset fb595abd6511 (Bug 1724080) for causing failures in browser_mixed_content_console.js CLOSED TREE

Push with failures: https://treeherder.mozilla.org/jobs?repo=autoland&group_state=expanded&collapsedPushes=842382&selectedTaskRun=SC1v4DpeSvqRcZRsqLiJrQ.0&resultStatus=testfailed%2Cbusted%2Cexception%2Cretry%2Cusercancel&revision=fb595abd6511860f98964ee8ccc97344a89651b1

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

Flags: needinfo?(ckerschb)

(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 ...

Flags: needinfo?(ckerschb)

(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.

Pushed by mozilla@christophkerschbaumer.com: https://hg.mozilla.org/integration/autoland/rev/181054194d83 Have https-first and https-only rules apply to speculative connections r=kershaw
Status: ASSIGNED → RESOLVED
Closed: 3 years ago3 years ago
Resolution: --- → FIXED
Target Milestone: --- → 96 Branch
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: