Closed Bug 2017712 Opened 8 months ago Closed 5 months ago

Firefox shows LNA prompts more eagerly than Chrome does, when there's a network hiccup that causes DNS to think public servers are at your local router address

Categories

(Core :: Networking: HTTP, defect, P2)

defect

Tracking

()

VERIFIED FIXED
152 Branch
Tracking Status
relnote-firefox --- 151+
firefox150 --- wontfix
firefox151 --- verified
firefox152 --- verified
firefox153 --- verified

People

(Reporter: dholbert, Assigned: valentin)

References

(Blocks 1 open bug)

Details

(Whiteboard: [necko-triaged][necko-priority-queue])

Attachments

(2 files, 6 external files, 1 obsolete file)

297 bytes, text/html
Details
297 bytes, text/html
Details

I'll post reliable STR in a later comment, but the tl;dr is that we've been having reports from Nightly users (myself included once) where something like the following occasionally happens:

  • computer resumes from sleep (with Firefox open), and/or there's an ISP hiccup and your network briefly goes down.
  • ...and then a bunch of web-apps suddenly show LNA prompts -- Google Docs, WhatsApp, Slack, I forget what else. (Probably any web-app that makes periodic requests for resources.)

It seems what's happening is:

  • Some local-network DNS server (on the machine or the router) gets confused and starts temporarily resolving all traffic to the router's IP address (let's say 192.168.1.1)
  • Then, a Google Docs tab that's currently-open makes a request for some resource on https://ssl.gstatic.com/ (just as an example)
  • The aforementioned DNS server gives back 192.168.1.1 as the IP address for ssl.gstatic.com
  • ...so the browser tries to establish an https connection to ssl.gstatic.com on IP address 192.168.1.1

This is where Firefox and Chrome diverge.

  • Firefox opens a connection to 192.168.1.1 on port 443 (because https), but yet doesn't go through the full https handshake. As long as there's some service listening on port 443, then we pause at that point and show the user a prompt before proceeding with the connection.
  • Chrome does the same except they go through the full https handshake -- requiring a valid/trusted certificate etc. -- before they show a prompt.

So: this means Firefox users see mysterious prompts out-of-the-blue, whereas Chrome users do not. (The request is ultimately doomed to fail in both, because of course 192.168.1.1 doesn't have a valid cerficiate for the google domain, nor does it have the requested resource. But Firefox nags the user with a prompt, and that's the issue here.)

There are several different sets of STR that are interesting to test here, to demonstrate the Firefox/Chrome difference that I mentioned in comment 0.

Here's the easiest STR, with a simple http server running on the requested port:

  1. Add the following line to your /etc/hosts file (on Ubuntu, or equivalent on other operating systems):
127.0.0.1 example.com
127.0.0.1 example.org
  1. Start a local http server listening on port 8080:
$ python3 -m http.server 8080
  1. Load testcase 1 or 2.

CHROME RESULTS:
No prompt. (In the web console, it shows that the load failed with net::ERR_SSL_PROTOCOL_ERROR.)

FIREFOX NIGHTLY RESULTS:
LNA prompt appears. If I allow it to proceed, then network devtools show that we end up failing the request with an ssl error as well (of course we do, because the server is an http server rather than an https server). But we don't get to that point until the user has allowed the LNA prompt.

Here's STR at the other end of the complexity spectrum (I did this in a VM to avoid polluting my actual environment):

  1. Ensure that you don't have any server running on port 8080 (e.g. the python web server from my previous comment), and that you've got example.org and example.com entries in /etc/hosts as described in previous comment.
  2. Install your own certificate authority using the mkcert utility:
sudo apt install mkcert

# This creates a root CA and makes Chrome trust it:
mkcert -install

# Generate a certificate for example.com:
mkcert example.com
  1. Install http-server and use it to listen to https requests (on port 8080 by default):
sudo apt install node-http-server node-opener
http-server --ssl --cert ~/example.com.pem --key ~/example.com-key.pem
  1. Visit https://example.com:8080 in Firefox -- this should give you a security error about the self-signed certificate -- and click through "Advanced..." to accept-the-risk and trust the self-signed certificate. (No need to do this in Chrome - mkcert handles this there.)
  2. Visit testcase 1 (example.com) and see what happens.
  3. Visit testcase 2 (example.org) and see what happens.

RESULTS:
Firefox Nightly shows LNA prompts for both testcases.
Chrome shows an LNA prompt for testcase 1 (because there's a valid ssl certificate, so Chrome makes it through the ssl handshake).
Chrome does not show any LNA prompt for testcase 2 (because the cert check failed -- the ssl certificate is for example.com, whereas the request was for example.org)

Sunil or Valentin - I'm hoping one of you can take it from here. Let me know if you need help reproducing/etc; hopefully comment 3 is a lightweight enough way to repro this. (Just remember to clean up your /etc/hosts when you're done. :) )

Flags: needinfo?(smayya)

Side note - Firefox release 147 does not hit this issue, because it's got a more permissive LNA configuration (which I think means it doesn't prompt at all for any of the situations noted above).

To test this bug in Firefox release, you need to toggle about:config pref network.lna.blocking to true -- that will make it behave like Nightly and start prompting as I've described in this bug.

Sunil is alway, so maybe Valentin can help.

(In reply to Daniel Holbert [:dholbert] from comment #0)

I'll post reliable STR in a later comment, but we've been having reports from Nightly users (myself included once) where something like the following happens:

  • computer resumes from sleep (with Firefox open)
  • A bunch of web-apps suddenly show LNA prompts -- Google Docs, WhatsApp, Slack, I forget what else. (Probably any web-app that makes periodic requests for resources.)

It seems what's happening is:

  • Some local-network DNS server (on the machine or the router) gets confused and starts temporarily resolving all traffic to the router's IP address (let's say 192.168.1.1)
  • Google Docs makes a request for some resource on https://ssl.gstatic.com/
  • The browser tries to establish an https connection to ssl.gstatic.com from 192.168.1.1

Do we know if Chrome also establishes connections to 192.168.1.1? Or is this a Firefox only issue?

Flags: needinfo?(smayya) → needinfo?(valentin.gosu)

LNA references fetch's obtain a connection, which says:

https://fetch.spec.whatwg.org/#create-a-connection

If establishing a connection does not succeed (e.g., a UDP, TCP, or TLS error), then return failure.

So for LNA that means, establishing a TCP connection doesn't mean we should prompt, but instead should do that only after TLS.
It does appear like Chrome is doing the right thing here.
The impact is not huge, except that Firefox users would encounter more prompts. And prompting for connections that would fail anyway is superfluous.

I'll look into fixing the issue.

Assignee: nobody → valentin.gosu
Severity: -- → S3
Status: NEW → ASSIGNED
Flags: needinfo?(valentin.gosu)
Priority: -- → P2
Whiteboard: [necko-triaged][necko-priority-queue]

(In reply to Kershaw Chang [:kershaw] from comment #7)

Do we know if Chrome also establishes connections to 192.168.1.1? Or is this a Firefox only issue?

It does, yeah -- the point here is that the browser is simply trusting the DNS server to resolve the domain (ssl.gstatic.com in this case), and the DNS server is on your local router and is temporarily resolving all domains to its own IP address, e.g. 198.168.1.1, as part of a captive-portal feature -- e.g. if your upstream internet connection drops and your router wants to redirect you to an informational page. And for ssl connections, the resulting network requests are doomed-to-fail because of course your router doesn't have a valid certificate for ssl.gstatic.com. And so when an already-open Google Docs tab makes a request to ssl.gstatic.com, that connection is doomed-to-fail (regardless of browser) -- but instead of silently failing, Firefox prompts the user about the local network connection before it gets far enough in establishing the connection to figure out that it's doomed anyway.

(In reply to Valentin Gosu [:valentin] (he/him) from comment #8)

The impact is not huge, except that Firefox users would encounter more prompts.

Just for prioritization purposes, I'd estimate the impact is a bit larger than this^ makes it out to be...

It's not just that this bug makes us show more prompts (e.g. Chrome shows some prompts, we show more), but rather:

  • we will show some prompts (on one or more tabs) for a specific identified situation where Chrome would not show any prompts (so it's N prompts for us vs. 0 prompts for Chrome)
  • ...and this is during a somewhat-common network condition (common enough that we've had internal folks running into this once or twice a month, and reporting it in the internal slack threads in #firefox and #project-lna starting in October here and more recently here; so it's something that a nontrivial fraction of our users will be sure to hit.)
  • ...with the prompt being misleading and needlessly alarming -- a user may be quite concerned to see a notification that Google Docs is attempting to crawl their network, and it may cause misdirected user paranoia, and/or hurt our own credibility in other security/permission-prompts.

I'll look into fixing the issue.

Thanks!

Note that we've also had at least one internal report of another use-case where someone's got a network configuration that may persistently cause this issue for tons of sites -- a user who's redirecting a set of advertising domains to 127.0.0.1, either in /etc/hosts or via ad-blocking software. Right now this will potentially cause every site with blocked ads to spawn an LNA prompt, only in Firefox. (there was a slack thread in #project-lna where chess.com came up as one example of a site that spawned a prompt, due to using an ad from a blocked domain).

I think fixing this bug would prevent the spurious-prompts in that use-case as well, as long as the ad-resources are referenced using secure HTTPS urls, which seems likely. (And to fix cases where ad resources are loaded on insecure http sites using insecure http URLs, we'll need to fix bug 2017732.)

See Also: → 2017732
See Also: → 2014694

Dear all,

We mentioned this difference in this LNA bug report, so the spec is updated for more consistent implementation across vendors: https://github.com/WICG/local-network-access/issues/103.

However, when Firefox displays the LNA prompt, it doesn't block TCP and TLS connections from public to local while awaiting user input. Worse, if the user chooses "Block", local TCP/TLS connections still go through, allowing ID sharing between public & local contexts (similar to the Local Mess abuse by Meta and Yandex). We shared a video demo here: https://github.com/WICG/local-network-access/issues/103#issuecomment-4007053666

Please let us know if you like us to file a separate bug report.

On behalf of the local mess team and collaborators...

(In reply to gunesacar from comment #12)

However, when Firefox displays the LNA prompt, it doesn't block TCP and TLS connections from public to local while awaiting user input. Worse, if the user chooses "Block", local TCP/TLS connections still go through,

Please let us know if you like us to file a separate bug report.

This sounds like a distinct defect from the issue that this bug report has been focusing on (summarized in comment 10). So: a new bug report would be great, yeah -- thanks!

(This bug report here is focused on Firefox showing potentially-misleading/confusing LNA prompts that Chrome never shows, in reasonably-common network-interruption scenarios, as discussed in comment 10. One possible resolution is that Chrome starts showing these LNA prompts as well -- it sounds like maybe they intend to do so eventually, per https://github.com/WICG/local-network-access/issues/103#issuecomment-3975812447 , and if/when that happens, then the discrepancy would presumably go away and perhaps this bug could be closed with no action needed. But in the meantime, until Chrome makes that change, it's worth tracking that Firefox Nightly users currently get a worse experience during these sorts of network interruptions discussed in comment 10, so that's what I'm aiming to have this bug focus on.)

(In reply to Daniel Holbert [:dholbert] from comment #14)

One possible resolution is that Chrome starts showing these LNA prompts as well -- it sounds like maybe they intend to do so eventually, per https://github.com/WICG/local-network-access/issues/103#issuecomment-3975812447 , and if/when that happens, then the discrepancy would presumably go away and perhaps this bug could be closed with no action needed.

Chrome's current intention is at some point to move to LNA checks being after DNS resolution but before connection establishment; we actually have our WebTransport LNA connection check pre-connection establishment (mostly because it was easier to do it there), but this bug is certainly highlighting some pitfalls that we may have to tackle as part of doing that.

(In reply to Valentin Gosu [:valentin] from comment #8)

It does appear like Chrome is doing the right thing here.
[...]
I'll look into fixing the issue.

Just checking in, is this still on your radar to align with Chrome's behavior soonish? (We got at least one internal report of someone hitting this bug on a flight today, where the in-flight router was likely doing some brief captive-portal shenanigans.)

(It's a bit more subtle than "Chrome is doing the right thing" per comment 15; but for now in any case, it seems like it's worth aligning with them to avoid user annoyance.)

(Also: I'm not sure if we have a bug yet for letting network.lna.blocking ride the trains to release - but if/when we do, I'd suggest that this bug should be a blocker for that.)

Flags: needinfo?(valentin.gosu)
See Also: → 2033733

For mochitests the relative path to the http2 cert is slightly different.
This change tries multiple paths to find the location of the cert.

Flags: needinfo?(valentin.gosu)
Pushed by valentin.gosu@gmail.com: https://github.com/mozilla-firefox/firefox/commit/ee0b9083c4b4 https://hg.mozilla.org/integration/autoland/rev/e69a44861479 Fix nodeServer cert path discovery r=necko-reviewers,jesup https://github.com/mozilla-firefox/firefox/commit/8b3356caac74 https://hg.mozilla.org/integration/autoland/rev/9074bb07ad58 Test that public-private LNA prompts are not displayed if the https cert validation fails r=necko-reviewers,sunil https://github.com/mozilla-firefox/firefox/commit/274344f6a416 https://hg.mozilla.org/integration/autoland/rev/7d0ca88452fd Defer LNA prompt for public-private https channels r=necko-reviewers,sunil,kershaw
Pushed by amarc@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/b06bfdebb5da https://hg.mozilla.org/integration/autoland/rev/9895d5b495da Revert "Bug 2017712 - Defer LNA prompt for public-private https channels r=necko-reviewers,sunil,kershaw" for causing bc failures @ browser_test_local_network_access_sni_leak

Backed out for causing bc failures

Flags: needinfo?(valentin.gosu)

(In reply to Daniel Holbert [:dholbert] from comment #6)

To test this bug in Firefox release, you need to toggle about:config pref network.lna.blocking to true -- that will make it behave like Nightly and start prompting as I've described in this bug.

FWIW this bug does actually currently affect release users who have ETP set to strict, because we toggle this^ pref to true for such users via the study "Local Network Access Rollout for ETP Strict". So once the patch re-lands, if it feels safe enough for uplift-to-151beta, we might want to uplift in order to fix this for affected ETP-strict users. (I just heard from one such internal user as discussed on slack.)

Pushed by smayya@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/2010991b766f https://hg.mozilla.org/integration/autoland/rev/ca783317583a Fix nodeServer cert path discovery r=necko-reviewers,jesup https://github.com/mozilla-firefox/firefox/commit/73bf045a74ce https://hg.mozilla.org/integration/autoland/rev/b92ef69b1746 Test that public-private LNA prompts are not displayed if the https cert validation fails r=necko-reviewers,valentin https://github.com/mozilla-firefox/firefox/commit/7bcac42a16bd https://hg.mozilla.org/integration/autoland/rev/41bad18d3d7b Defer LNA prompt for public-private https channels r=necko-reviewers,kershaw
Flags: needinfo?(valentin.gosu)

(Marking 151 as affected, for some users, per comment 23.)

Pushed by amarc@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/f2a38584c6b7 https://hg.mozilla.org/integration/autoland/rev/7109c8e2cee0 Revert "Bug 2017712 - Defer LNA prompt for public-private https channels r=necko-reviewers,kershaw" for causing bc failures @ browser_test_local_network_access_sni_leak

Backed out for causing bc failures

Flags: needinfo?(valentin.gosu)
Flags: needinfo?(valentin.gosu)
Pushed by valentin.gosu@gmail.com: https://github.com/mozilla-firefox/firefox/commit/f8701ce192b2 https://hg.mozilla.org/integration/autoland/rev/0b1e09c650b5 Fix nodeServer cert path discovery r=necko-reviewers,jesup https://github.com/mozilla-firefox/firefox/commit/679fb6ee2440 https://hg.mozilla.org/integration/autoland/rev/38cb72e407b9 Test that public-private LNA prompts are not displayed if the https cert validation fails r=necko-reviewers,valentin https://github.com/mozilla-firefox/firefox/commit/e46222ad1776 https://hg.mozilla.org/integration/autoland/rev/27153604bd16 Defer LNA prompt for public-private https channels r=necko-reviewers,kershaw
Status: ASSIGNED → RESOLVED
Closed: 5 months ago
Resolution: --- → FIXED
Target Milestone: --- → 152 Branch

The patch landed in nightly and beta is affected.
:valentin, is this bug important enough to require an uplift?

For more information, please visit BugBot documentation.

Flags: needinfo?(valentin.gosu)

uplift to beta requested via lando

Flags: needinfo?(valentin.gosu)

For mochitests the relative path to the http2 cert is slightly different.
This change tries multiple paths to find the location of the cert.

Original Revision: https://phabricator.services.mozilla.com/D295844

Attachment #9582724 - Flags: approval-mozilla-beta?
Attachment #9582725 - Flags: approval-mozilla-beta?

firefox-beta Uplift Approval Request

  • User impact if declined/Reason for urgency: This is source of confusion/annoyance for folks with LNA enabled (either completely, or through ETP strict) when their routers temporarily lose connectivity and act as a captive portal.
  • Code covered by automated testing?: yes
  • Fix verified in Nightly?: yes
  • Needs manual QE testing?: yes
  • Steps to reproduce for manual QE testing: See comment 3
  • Risk associated with taking this patch: medium
  • Explanation of risk level: The patch just landed on Nightly, and touches some important parts of the connection handling.
  • String changes made/needed?: None.
  • Is Android affected?: yes
Attachment #9582726 - Flags: approval-mozilla-beta?
Flags: qe-verify+

firefox-beta Uplift Approval Request

  • User impact if declined/Reason for urgency: LNA feature will be rolled out to all users of 151. Without this, we they might see unexpected prompt on sites whenever there is a network fluctuation.
  • Code covered by automated testing?: yes
  • Fix verified in Nightly?: yes
  • Needs manual QE testing?: no
  • Steps to reproduce for manual QE testing:
  • Risk associated with taking this patch: low
  • Explanation of risk level: Feature limited only to LNA check.
  • String changes made/needed?: No
  • Is Android affected?: yes
Attachment #9582793 - Flags: approval-mozilla-beta?

For mochitests the relative path to the http2 cert is slightly different.
This change tries multiple paths to find the location of the cert.

Original Revision: https://phabricator.services.mozilla.com/D295844

Relnote to be added only if the patches gets uplifted to beta.

[Why is this notable]: LNA feature will be enabled to all users of 151 gradually via nimbus.
[Affects Firefox for Android]:No

[Suggested wording]:
Local network access restrictions are now being extended to all users. Firefox will require websites to request your permission before connecting to devices on your local network or to apps and services on your device. Previously limited to users with Enhanced Tracking Protection set to Strict, this protection is now rolling out gradually to all users .

[Links (documentation, blog post, etc)]: SUMO Page

relnote-firefox: --- → ?
Attachment #9582793 - Flags: approval-mozilla-beta?
QA Whiteboard: [uplift][qa-ver-needed-c152/b151]

A patch has been attached on this bug, which was already closed. Filing a separate bug will ensure better tracking. If this was not by mistake and further action is needed, please alert the appropriate party. (Or: if the patch doesn't change behavior -- e.g. landing a test case, or fixing a typo -- then feel free to disregard this message)

Attachment #9582793 - Attachment is obsolete: true
Attachment #9582724 - Flags: approval-mozilla-beta? → approval-mozilla-beta+
Attachment #9582725 - Flags: approval-mozilla-beta? → approval-mozilla-beta+
Attachment #9582726 - Flags: approval-mozilla-beta? → approval-mozilla-beta+

Added to the Fx151 beta release notes, please allow 30 minutes for the site to update.
Keeping the relnote-firefox flag as ? to keep it on the radar for inclusion in the final Fx151 release notes.

Added to the final Fx151 release notes

Hello, Daniel! Could you please check if this issue is fixed on latest Beta 152 and Release 151?

I'm not able to reproduce the issue on my environment with Ubuntu 26 using the info from comment 3, on an affected Nightly build (2026-02-18).

Flags: needinfo?(dholbert)

Sure. Unfortunately it looks like this is not fixed. :-/

I tested Nightly from soon after this landed (2026-05-03) as well as current Nightly (2026-05-20).
Using STR in comment 3 and comment 4, Nightly is still prompting me in every case. So I didn't bother testing release/beta since the uplifted patch presumably wouldn't have mattered there either.

valentin, mind taking another look? (Presumably I should file a new bug, since we had a patch land & get uplifted here, which would make reopening a bit clumsy at this point. Is there verification that should be done for whatever behaivor-change the patch that landed did actually make, and would you mind doing that verification?)

Flags: needinfo?(dholbert) → needinfo?(valentin.gosu)

Oh, hold up... Maybe the issue is that my STR are using localhost, and IIRC we ended up deciding to keep prompting for that case (since localhost is a juicier target and less likely to be serving as a captive-portal); and we decided to just prevent the prompt when another device on your network is serving as a captive portal.

So the STR I should really be using involve running the web server on a different machine (server) from the one running Firefox (client), and putting the server's ip address in /etc/hosts instead of 127.0.0.1 (in the comment 3 STR).

OK, phew - with that adjustment, this is tentatively looking good.

Comment 3 STR (amended per comment 45):

  • Nightly 2025-05-01: Bad (prompt shown when loading testcase 1 and testcase 2)
  • Nightly 2025-05-03: Good (no prompts)
  • Nightly 2025-05-20: Good (no prompts)

So that's looking fixed. Now I'll test comment 4 STR and then beta/release on both sets of STR and report back

Flags: needinfo?(valentin.gosu)

Still testing Nightly versions...

Comment 4 STR (amended per comment 45):

  • Nightly 2025-05-01: Bad (prompt shown when loading testcase 1 and testcase 2)
  • Nightly 2025-05-03: Good (prompt shown for testcase 1, but no prompt for testcase 2 -- same as Chrome)
  • Nightly 2025-05-20: Good (prompt shown for testcase 1, but no prompt for testcase 2 -- same as Chrome)

Things still looking good/as-expected.

Now testing Firefox 150.0, 151.0, & 152.0b1. I'm testing all of them with network.lna.blocking manually set to true (that's the default in 152, and it may be imposed as a default in 151, particularly for users who've got ETP strict).

150 is expected-bad, while 151 & 152 are expected-good.

Comment 3 STR (amended per comment 45):

  • Firefox 150.0: Bad (prompt shown when loading testcase 1 and testcase 2)
  • Firefox 151.0: Good (no prompts)
  • Firefox 152.0b1: Good (no prompts)

Comment 4 STR (amended per comment 45):

  • Firefox 150.0: Bad (prompt shown when loading testcase 1 and testcase 2)
  • Firefox 151.0: Good (prompt shown for testcase 1, but no prompt for testcase 2 -- same as Chrome)
  • Firefox 152.0b1: Good (prompt shown for testcase 1, but no prompt for testcase 2 -- same as Chrome)

So from my perspective, this is VERIFIED FIXED for Firefox 151 release and 152b1 (and Nightly 153, per previous 2 comments)

Thanks, Daniel, for testing this! Appreciate it.

QA Whiteboard: [uplift][qa-ver-needed-c152/b151] → [uplift][qa-ver-done-c152/b151]
Flags: qe-verify+
Blocks: 2042482

(In reply to Daniel Holbert [:dholbert] from comment #45)

IIRC we ended up deciding to keep prompting for that case (since localhost is ... less likely to be serving as a captive-portal);

Hmm, so actually there are cases where localhost ends up behaving something like a captive-portal -- see bug 2042482 where AdGuard seems to be using DNS to filter ad traffic and resolve ad domains as a localhost address, which triggers an LNA prompt. :-/

You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: