Open Bug 1642623 Opened 4 years ago Updated 2 years ago

User's search term is accidentally sent to ISP without user's consent.

Categories

(Firefox :: Address Bar, defect, P3)

75 Branch
Unspecified
Windows 10
defect

Tracking

()

People

(Reporter: decoder, Unassigned)

References

Details

(Keywords: privacy, sec-low, Whiteboard: [snt-scrubbed][search-privacy])

This is an external bug report received by Duy Khuong via security@mozilla.org:

Description:

When an user types a search term (e.g. "a-very-sensitive-word") into the address bar and enter, the quick search feature will bring up search results from a search engine (either from Google or DuckDuckGo) which is an expected behavior.
However, the search term ("a-very-sensitive-word") is also "mistakenly" sent to one of the (DNS) servers of the user's ISP. The user's privacy is compromised.

The issue happens even if DoH (DNS over HTTPS) is in place. Even though, this should not happen in any circumstances, with or without DoH. Any information users type or search for must not not be sent out (especially to the ISP) without the users' consent.

Other observation:

  • The issue only happens when the search term is ONE word ("word", "one-word", "many-words-without-spaces"... are eligible ones).
  • The issue does not occur when the search term consist of multiple words (i.e. "this will not cause the issue").
  • ISP's server address is set (by default) as one of the "Connection-specific DNS suffixes". THIS IS THE MOST IMPORTANT POINT!

Details:

  • The user wants the highest level of security & privacy, so he already enabled DoH in Firefox setting.
  • He also set DuckDuckGo as the default search engine in Firefox, to protect his privacy.
  • He types some random search in the address bar of Firefox.
  • He wants to confirm if DoH really works by checking DNS logs (with command "ipconfig /displaydns").
  • SURPRISINGLY, the term he used for his search apeared in the DNS log, in one of the queries sent to ISP's servers.

Analysis:

  • An ISP's server address is set as one of the "Connection-specific DNS suffixes", when DHCP is used.
  • With a DNS suffix is set, Firefox (mis-)interpret the search term (followed by the suffix, "search-term.[suffix]") as a potentially-valid domain name and therefore sends a DNS query to ask for its IP address.
  • The problem is, despite the fact that DoH is enabled by the user, when sending the DNS query, Firefox does not treat the "search-term.[suffix]" in the same way as other domain names and therefore send it in plain text.
  • As a consequence, the DNS query is logged and the search-term is recorded and sent to the suffix server (which belongs to ISP), without user's consent.

Impact/Risk:

  • The ISP can track user's activities and use his searching history for the purposes against the user.
  • A malicious actor on the network can setup a rogue DHCP server and intentionally set the user's DNS suffixes to one of the attacker's servers. By monitoring that server, the attacker can track the user's activities and use his searching history for malicious purposes (e.g. selling data, advertising, ransom,...)

Mitigation (temporary workaround until Firefox provides the fix):

  • Set IP address manually (do not use DHCP).
  • Make sure DNS suffixes do not consist of any unusual addresses.

Christian, is it really useful to keep this hidden given the public blogpost and public chromium issue?

Marco, thoughts? The Chromium issue has some interesting discussion... I'm not sure what we can do here without breaking the intranet usecase.

Component: Search → Address Bar
Flags: needinfo?(mak)
Flags: needinfo?(choller)

(In reply to :Gijs (he/him) from comment #1)

Christian, is it really useful to keep this hidden given the public blogpost and public chromium issue?

Absolutely not but I cannot unhide it myself. Please feel free to do so :)

Flags: needinfo?(choller)
Group: firefox-core-security

There are a couple things in urlbar that can start dns connections:

  1. speculative connections. These are used to warm up the connection before the user visits it, to speed up browsing. We startup a speculative connection when the first urlbar result is received and it's a search or autofill. They can always be disabled setting browser.urlbar.speculativeConnect.enabled to false.
  2. Single words that are search for, but may actually be local domains, to show the "Did you mean to go to" prompt. There's no pref controlling this, potentially one could be introduced.

If the matter is giving users a way to escape the behavior, we could easily introduce a pref.
If the matter is respecting DOH, I'm not sure I have the knowledge to propose the right fix.
If the matter is stop doing it by default, it would likely break users or make browsing slower.

In our case if we'd stop doing it we wouldn't completely break intranet (at least from Firefox 78 on) because we have nice domain and domain suffix prefs that allow specific entries, and a few very common suffixes are already handled by default. Though we would still break less-technical users trying to access intranet without prior appropriate configuration.

We currently handle it better than Chrome in the sense we don't query if the string contains any of "@:/?#"
We also won't send words that can be recognized as a valid url/origin (depending on PSL, or IP addresses), since we only look for single words that can't be recognized as a valid origin.

My suggestion would be to introduce a pref that allows disabling the dns check for single words behavior (so disable the "Did you mean to go to" bar), so one can set the speculativeConnect pref and this one to prevent any kind of info leaking towards the dns.
We should probably also avoid the dns lookup in PB mode, we don't seem to atm (we do for speculativeConnect).
I'd do those in a dependency.

Then keep this open to keep monitoring what Chrome plans to do; so far I went through their suggestions and we already do some of them, we don't do:

  • use history to check if the origin appears somewhere in it
  • avoid in case of policies (or provide policy)
  • use hosts

Though some of these suggestions appear expensive or non-resolutive.

Flags: needinfo?(mak)
Depends on: 1642943

Valentin, I see that you are working on bug 1544233; our need here, if we want to use an heuristic, rather than exposing a pref that the user may discover too late, would be some API from the network code telling us whether the user may be resolving everything remotely.
If we can be relatively sure all the addresses are resolved remotely (DOH), then we can completely skip this post-facto dns resolve after search, because it's unlikely a remote resolver would handle non-dotted words or invalid suffixes.

How complicate would be, after bug 1544233 to detect things like:

  1. the system has no hosts or just the default one
  2. we are using DOH

In addition we likely want to check:
I. the system is part of a domain (enterprise)
II. the system is using policies (we can already detect this, I assume)

There's still some edge cases there, like special suffixes (.onion or openNIC) that some remote resolver may recognize, others not. We could either:
a. just suggest to use browser.fixup.dns_first_for_single_words
b. provide a tri-bool pref for this post-facto dns feature: 0 never, 1 default (heuristic), 2 always
c. just add them to our list of recognized suffixes, though then we'd need some policy for inclusion

Flags: needinfo?(valentin.gosu)

So, just before anything else, I want to mention that the fact that we don't use TRR for things that match the DNS suffix is a feature, not a bug. See bug 1582472. We did this to mitigate split horizon situations, where a user might want to reach router.lan or internal-company-server.corp.
It is guarded by the network.notify.dnsSuffixList pref on Windows, but can't be disabled on other platforms.

(In reply to Marco Bonardo [:mak] from comment #4)

How complicate would be, after bug 1544233 to detect things like:

  1. the system has no hosts or just the default one

Do you mean in /etc/hosts or are you referring to the DNS suffix?

  1. we are using DOH

If we are using DoH can be checked. See this

The problem is that in mode2 (TRR-first) we can't know for sure if a request will succeed when using the TRR server or if we fallback to using native DNS.

and also in mode3 (TRR-only) but to lesser extent there are cases where we might use native DNS (the suffix list, and domains in the excluded-domains pref are some examples).

In addition we likely want to check:
I. the system is part of a domain (enterprise)

nsINetworkLinkService.dnsSuffixList

Flags: needinfo?(valentin.gosu)

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

(In reply to Marco Bonardo [:mak] from comment #4)

How complicate would be, after bug 1544233 to detect things like:

  1. the system has no hosts or just the default one

Do you mean in /etc/hosts or are you referring to the DNS suffix?

/etc/hosts

(In reply to Marco Bonardo [:mak] from comment #6)

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

(In reply to Marco Bonardo [:mak] from comment #4)

How complicate would be, after bug 1544233 to detect things like:

  1. the system has no hosts or just the default one

Do you mean in /etc/hosts or are you referring to the DNS suffix?

/etc/hosts

I'll make sure to add this ability to bug bug 1544233 , but this should be well specified.
The hosts file normally has localhost, ip6-localhost, and maybe some .local ones. I can make the list available through an API, and let you decide what "the default one" means, or if there aren't any ambiguities it could be computed during parsing.

So my questions are:

  1. What characteristics does a non-default /etc/hosts have, vs a default one?
  2. What do we intend to do differently when that happens?

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

So my questions are:

  1. What characteristics does a non-default /etc/hosts have, vs a default one?
  2. What do we intend to do differently when that happens?

It's a tricky question. First, fixup recognizes most hosts that end in .local, .internal and other well defined suffixes, in those cases we'd have no problem here because we know those hosts are valid.
The problem is string with totally unknow suffixes (not in the PSL and not in the fixup lists) and non-dotted strings. Anything that URIFixup thinks it may be a search.
I'd assume a good initial heuristic may be "/etc/hosts only contains 'localhost'".

We'd like to use that info to create an heuristic that avoids sending a string to the DNS when the user is unlikely to be using an intranet.
What we do right now, when a host is not recognized by URIFixup is: execute a search, then fire a DNS request to eventually show a "Did you mean to go to http://site/?" prompt.
We could avoid the DNS lookup if we knew the user is unlikely to be using intranet hosts.

So for example a word is unlikely an intranet host if:

  • user is using DOH
  • /etc/hosts only contains localhost
  • no policies are in use
  • the computer is not enrolled in a domain
Severity: -- → S3
Priority: -- → P2

Hello, this is me who submitted the report via email.
Could someone let me know if we can have a fix for this bug soon, please?
Thank you and Best regards,
Duy Khuong

(In reply to duykham+bugzilla from comment #9)

Hello, this is me who submitted the report via email.
Could someone let me know if we can have a fix for this bug soon, please?
Thank you and Best regards,
Duy Khuong

With revision D88967 (https://hg.mozilla.org/integration/autoland/rev/c656168bb863) Firefox 82.0, if you set network.trr.split_horizon_mitigations: false the search term no longer leaks (I think?)

See Also: → CVE-2020-26966

This should not happen anymore because we disabled by default the "did you mean to go to " notification bar, that was starting the DNS request.
Something we could do in the future is to measure the number of users who flipped the pref back to see how many users this affects, and eventually provide a heuristic per comment 8 to enable it only when an intranet is "detected".

Priority: P2 → P3
Whiteboard: [snt-scrubbed][search-privacy]
You need to log in before you can comment on or make changes to this bug.