Open Bug 1799411 Opened 2 years ago Updated 5 months ago

DNS leaks with proxy extension

Categories

(WebExtensions :: General, defect, P3)

Firefox 109
defect

Tracking

(firefox107 affected, firefox108 affected, firefox109 affected)

Tracking Status
firefox107 --- affected
firefox108 --- affected
firefox109 --- affected

People

(Reporter: tomacat, Unassigned)

References

(Blocks 1 open bug)

Details

(Whiteboard: [design-decision-needed])

User Agent: Mozilla/5.0 (X11; Linux x86_64; rv:106.0) Gecko/20100101 Firefox/106.0

Steps to reproduce:

For the origin thread please see "DNS leaks about browser.dns API": https://bugzilla.mozilla.org/show_bug.cgi?id=1618271

  1. Install the extension uBlock Origin 1.44.4
  2. Prepare a Socks5 proxy. (If you don't have one, but Torbrowser provide it, it listens on socks5://localhost:9150)
  3. Using the DNS leaks test service like: ipleak.net, dnsleaktest.com, whatismydnsresolver.com. In the meantime, the command sudo tcpdump udp port 53 also use to figure out if DNS leaks has happened.

I come up with 4 use cases to test whether this defect which I mentioned on https://bugzilla.mozilla.org/show_bug.cgi?id=1618271 was fixed, and it was fixed:

  • Case 1
    network.proxy.socks = localhost
    network.proxy.socks_port = 1080
    network.proxy.socks_remote_dns = true //Proxy DNS when using SOCKS v5
    network.proxy.type = 5 //Use system proxy settings (Default value)

Result: DNS Leaks (Expected, it should be.)

  • Case 2
    network.proxy.socks = localhost
    network.proxy.socks_port = 1080
    network.proxy.socks_remote_dns = true
    network.proxy.type = 0 //No proxy

Result: DNS Leaks (Expected, it should be.)

  • Case 3
    network.proxy.socks = localhost
    network.proxy.socks_port = 1080
    network.proxy.socks_remote_dns = true
    network.proxy.type = 1 //Manual proxy configuration

Result: No Leaks

  • Case 4
    network.proxy.socks = localhost
    network.proxy.socks_port = 1080
    network.proxy.socks_remote_dns = true
    network.proxy.type = 2 //Automatic proxy configuration URL

Result: DNS Leaks (Expected, it should be.)

  • Case 5
    network.proxy.socks = localhost
    network.proxy.socks_port = 1080
    network.proxy.socks_remote_dns = true
    network.proxy.type = 4 //Auto-detect proxy settings for this network

Result: DNS Leaks (Expected, it should be.)

Many Firefox users on Reddit/Github complain their use of VPN extension still have these DNS Leaks. In my test case, I choose two popular proxy manager extensions, FoxyProxy Standard and Proxy SwitchyOmega (both of them are open source.) Here are steps to use the proxy manager extension to control Firefox proxy settings:

  • FoxyProxy Standard --> options --> Add --> Proxy Type: SOCKS5; Proxy IP address or DNS name: localhost; Port: 1080 --> Save. FoxyProxy Standard --> localhost:1080 (for all URLs)
  • SwitchyOmega --> Profile :: proxy --> Proxy servers --> SOCKS5 localhost 1080 --> Apply changes. SwitchyOmega --> proxy

The following test cases will use a proxy extension. You only need to enable one proxy extension, but I confirmed whatever use FoxyProxy or SwitchyOmega this situation will happen.

Actual results:

  • Case 6
    network.proxy.socks_remote_dns = true //Proxy DNS when using SOCKS v5
    network.proxy.type = 5 //Use system proxy settings (Default value)

Result: DNS Leaks

  • Case 7
    network.proxy.socks_remote_dns = true
    network.proxy.type = 0 //No proxy

Result: DNS Leaks

  • Case 8
    network.proxy.socks_remote_dns = true
    network.proxy.type = 1 //Manual proxy configuration

Result: DNS Leaks

  • Case 9
    network.proxy.socks_remote_dns = true
    network.proxy.type = 2 //Automatic proxy configuration URL

Result: DNS Leaks

  • Case 10
    network.proxy.socks_remote_dns = true
    network.proxy.type = 4 //Auto-detect proxy settings for this network

Result: DNS Leaks

  • Case 11
    network.proxy.socks = localhost
    network.proxy.socks_port = 1080
    network.proxy.socks_remote_dns = true
    network.proxy.type = 5 //Use system proxy settings (Default value)

Result: DNS Leaks

  • Case 12
    network.proxy.socks = localhost
    network.proxy.socks_port = 1080
    network.proxy.socks_remote_dns = true
    network.proxy.type = 0 //No proxy

Result: DNS Leaks

  • Case 13
    network.proxy.socks = localhost
    network.proxy.socks_port = 1080
    network.proxy.socks_remote_dns = true
    network.proxy.type = 1 //Manual proxy configuration

Result: No DNS Leaks

  • Case 14
    network.proxy.socks = localhost
    network.proxy.socks_port = 1080
    network.proxy.socks_remote_dns = true
    network.proxy.type = 2 //Automatic proxy configuration URL

Result: DNS Leaks

  • Case 15
    network.proxy.socks = localhost
    network.proxy.socks_port = 1080
    network.proxy.socks_remote_dns = true
    network.proxy.type = 4 //Auto-detect proxy settings for this network
    Result: DNS Leaks

Expected results:

In the proxy manager extension case, only configuring with "Manual proxy configuration", setting SOCKS Host/Port, and checking "Proxy DNS when using SOCKS v5" will prevent DNS Leaks (Case 13). I expected that there is no DNS Leaks in Case 6-12, 14, 15.

Component: Untriaged → Networking
Product: Firefox → Core
See Also: → 1618271

The observed behavior being depend on the network.proxy.type may not be too surprising considering that the socks_remote_dns pref is only checked when a manual proxy is set: https://searchfox.org/mozilla-central/rev/3c194fa1d6f339036d2ec9516bd310c6ad612859/netwerk/dns/DNSServiceBase.cpp#52-55

What request triggers the DNS leak? The proxy.onRequest event handler can define request-specific proxy handlers (and even specify that the socks proxy supports dns (source)), but that requires (1) that the request is seen and (2) that the TRANSPARENT_PROXY_RESOLVES_HOST flag internally propagates to all places where the DNS check is used. I don't know for sure whether that is the case, but I hope that this info may help the network people with their investigation.

I found https://github.com/uBlockOrigin/uBlock-issues/issues/1743#issuecomment-932360116:

the issue is uBO's DNS query not being proxied by another extension doing the proxying on-the-fly through proxy.onRequest(), which is expected as extensions can't interfere which each other's requests

which is expected as extensions can't interfere which each other's requests

Just curious, I write a userscript in Greasemonkey Extension to fetch one URL which is blocked by uBlock Origin. But I found that uBlock Origin can block that URL. I don't know these proxy DNS things.

(In reply to hxxtom from comment #3)

which is expected as extensions can't interfere which each other's requests

Just curious, I write a userscript in Greasemonkey Extension to fetch one URL which is blocked by uBlock Origin. But I found that uBlock Origin can block that URL. I don't know these proxy DNS things.

I also can confirm that one extension can manage whether the other extension's request is proxied. ("Tools" Menu --> Browser Tools --> Browser Toolbox. You can see all requests (including the extensions' requests) in Firefox. One request's "Remote IP" is 0.0.0.0:443, which means that the request was proxied.)

I think the problem here is that using a proxy extension doesn't really change the proxy prefs, it only applies the proxy settings to the http requests made by Firefox. For example, if you use an extension to configure Firefox to use a socks proxy, you should observe all http requests are using that proxy. However, if you open about:config and see the value of network.proxy.type, the value is still 5.

According to our current implementation, the only way to avoid DNS leak is setting the pref network.proxy.type to 1, using a socks proxy, and set network.proxy.socks_remote_dns to true.

Maybe the way to move forward is allowing extensions to set the necessary proxy prefs directly.
Rob, what do you think?

Flags: needinfo?(rob)

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

I think the problem here is that using a proxy extension doesn't really change the proxy prefs, it only applies the proxy settings to the http requests made by Firefox. For example, if you use an extension to configure Firefox to use a socks proxy, you should observe all http requests are using that proxy. However, if you open about:config and see the value of network.proxy.type, the value is still 5.

According to our current implementation, the only way to avoid DNS leak is setting the pref network.proxy.type to 1, using a socks proxy, and set network.proxy.socks_remote_dns to true.

Maybe the way to move forward is allowing extensions to set the necessary proxy prefs directly.
Rob, what do you think?

Extensions can already set these prefs: https://searchfox.org/mozilla-central/rev/0062309958c212504556ae21a7e3eb120c9bd093/toolkit/components/extensions/parent/ext-proxy.js#58,60

I imagine that the extensions use proxy.onRequest, to select specific proxies for individual requests. Ideally proxy.onRequest should be available to specify proxies for all requests, at least these that web content can generate.

Hence my request for what request triggers the proxy leak:

(In reply to Rob Wu [:robwu] from comment #1)

What request triggers the DNS leak? The proxy.onRequest event handler can define request-specific proxy handlers (and even specify that the socks proxy supports dns (source)), but that requires (1) that the request is seen and (2) that the TRANSPARENT_PROXY_RESOLVES_HOST flag internally propagates to all places where the DNS check is used. I don't know for sure whether that is the case, but I hope that this info may help the network people with their investigation.

For regular http(s)/ws(s) requests, I would expect proxy.onRequest to be able to intercept all relevant requests. I haven't checked, but I would not be very surprised if other protocols (e.g. from WebRTC, ICE to TURN/STUN servers) exhibit leaks, since these don't use http.

Flags: needinfo?(rob)

(In reply to Rob Wu [:robwu] from comment #7)

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

I think the problem here is that using a proxy extension doesn't really change the proxy prefs, it only applies the proxy settings to the http requests made by Firefox. For example, if you use an extension to configure Firefox to use a socks proxy, you should observe all http requests are using that proxy. However, if you open about:config and see the value of network.proxy.type, the value is still 5.

According to our current implementation, the only way to avoid DNS leak is setting the pref network.proxy.type to 1, using a socks proxy, and set network.proxy.socks_remote_dns to true.

Maybe the way to move forward is allowing extensions to set the necessary proxy prefs directly.
Rob, what do you think?

Extensions can already set these prefs: https://searchfox.org/mozilla-central/rev/0062309958c212504556ae21a7e3eb120c9bd093/toolkit/components/extensions/parent/ext-proxy.js#58,60

Thanks, I am not aware of this. So, looks like it a extension's responsibility to set these prefs correctly?

Hence my request for what request triggers the proxy leak:

It's not just requests can trigger DNS lookups. Using browser.dns.resolve or DNS prefetch can also do DNS lookups.

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

(In reply to Rob Wu [:robwu] from comment #7)

Extensions can already set these prefs: https://searchfox.org/mozilla-central/rev/0062309958c212504556ae21a7e3eb120c9bd093/toolkit/components/extensions/parent/ext-proxy.js#58,60

Thanks, I am not aware of this. So, looks like it a extension's responsibility to set these prefs correctly?

Partially yes. In comment 7 I mentioned why extensions would use proxy.onRequest instead of setting just one blanket pref.

Hence my request for what request triggers the proxy leak:

It's not just requests can trigger DNS lookups. Using browser.dns.resolve or DNS prefetch can also do DNS lookups.

I'm examining requests beyond http(s) and DNS, because the issue here is not just a DNS leak, but more broadly leaking outside a proxy.
The proxy.onRequest API works well for http(s), but I question its completeness for non-http(s) requests... It works via nsIProtocolProxyService, which sounds very generic, but the steps before dispatching the proxy.onRequest event sometimes assumes the channel to be a http channel.

Looks like my hunch is correct: proxy.onRequest fails miserably: WebRTC in bug 1790270, non-http (FTP) in bug 1567900.
The non-http request case can be addressed by fixing the proxy.onRequest implementation, to be independent of http channels.
I haven't looked at the implementation details of WebRTC, so I don't readily have anything to comment there.

Is the recommendation to set a blanket pref for all requests as a fallback? What is available if a user/extension wants to configure a proxy for specific websites (or container tabs) only?

See Also: → 1790270, 1567900
See Also: → 1791243

Looks like my hunch is correct: proxy.onRequest fails miserably: WebRTC in bug 1790270, non-http (FTP) in bug 1567900.

FWIW, FTP is no longer supported in Firefox.

The non-http request case can be addressed by fixing the proxy.onRequest implementation, to be independent of http channels.
I haven't looked at the implementation details of WebRTC, so I don't readily have anything to comment there.

Is the recommendation to set a blanket pref for all requests as a fallback? What is available if a user/extension wants to configure a proxy for specific websites (or container tabs) only?

Maybe we need another pref to allow extensions to control whether to enable proxy DNS globally (for every DNS lookups)?

It seems the questions here are more about what APIs/interface we want to expose to web extensions, so I'd like to change the component to WebExtension. Please file another networking bug if you need any change in networking layer. Thanks.

Component: Networking → General
Product: Core → WebExtensions

Hello,

I tried reproducing the issue but I’m not sure I’m correctly following the STR. Here is what I did so far:

  1. Installed latest version of uBlock Origin
  2. Installed Foxy Proxy Standard, configured it and enabled it as mentioned here: “FoxyProxy Standard --> options --> Add --> Proxy Type: SOCKS5; Proxy IP address or DNS name: localhost; Port: 1080 --> Save. FoxyProxy Standard --> localhost:1080 (for all URLs)”
  3. Tried accessing ipleak.net, dnsleaktest.com, whatismydnsresolver.com and surfshark.com/dns-leak-test, however I was greeted by a “The proxy server is refusing connections” page and the websites don’t load.
  4. Went to about:config and started to manually configure the network.proxy.socks_remote_dns and network.proxy.type as mentioned in the “Actual results” section of the report.
  5. Accessed ipleak.net, dnsleaktest.com, whatismydnsresolver.com and surfshark.com/dns-leak-test again and got the same results as in Step 3.

Would you mind providing some more detailed steps to reproduce? Thank you !

Flags: needinfo?(hxxtom)
Whiteboard: [design-decision-needed]

(In reply to Alex Cornestean from comment #11)

  1. Tried accessing ipleak.net, dnsleaktest.com, whatismydnsresolver.com and surfshark.com/dns-leak-test, however I was greeted by a “The proxy server is refusing connections” page and the websites don’t load.

A real socks5 proxy is required here. I recommend use Tor Browser which can download from https://www.torproject.org/download/. Tor browser open socks proxy on 127.0.0.1:9150. Replace 1080 with 9150 in the extension.

I read nayinain 's bug 1678978, his extension is more simpler and it do almost same things as I do. Reproduce steps could use his webext-DNSLeaksTest.zip instead of install uBlock Origin and FoxyProxy extension.

Flags: needinfo?(hxxtom)

Hello hxxtom and thank you for the additional info!

I believe I reproduced the issue on the latest Nightly (109.0a1/20221121153827) and Release (107.0/20221110173214) under Windows 10 x64.

I installed the Tor browser as suggested in Comment 12, which indeed solved my initial issues of the test pages not loading.
I installed uBlock Origin and Foxy Proxy Standard as per the original STR and configured Foxy Proxy Standard with SOCKS5/localhost/9150.

I then went and checked each case mentioned in the original report on surfshark.com/dns-leak-test with the following results:

Nightly (109.0a1/20221121153827)
Case 6 - confirmed
network.proxy.socks_remote_dns = true //Proxy DNS when using SOCKS v5
network.proxy.type = 5 //Use system proxy settings (Default value)
Result: DNS Leaks

Case 7 - confirmed
network.proxy.socks_remote_dns = true
network.proxy.type = 0 //No proxy
Result: DNS Leaks

Case 8 - confirmed
network.proxy.socks_remote_dns = true
network.proxy.type = 1 //Manual proxy configuration
Result: DNS Leaks

Case 9 - confirmed
network.proxy.socks_remote_dns = true
network.proxy.type = 2 //Automatic proxy configuration URL
Result: DNS Leaks

Case 10 - confirmed
network.proxy.socks_remote_dns = true
network.proxy.type = 4 //Auto-detect proxy settings for this network
Result: DNS Leaks

Case 11 - confirmed
network.proxy.socks = localhost
network.proxy.socks_port = 9150
network.proxy.socks_remote_dns = true
network.proxy.type = 5 //Use system proxy settings (Default value)
Result: DNS Leaks

Case 12 - confirmed
network.proxy.socks = localhost
network.proxy.socks_port = 9150
network.proxy.socks_remote_dns = true
network.proxy.type = 0 //No proxy
Result: DNS Leaks

Case 13 - I get DNS leak according to surfshark.com/dns-leak-test, however the list produced by the website check was much much smaller (2 IP addresses only as opposed to around 9 to 10 in the other cases) so I don’t really know if this counts as a leak or not.
network.proxy.socks = localhost
network.proxy.socks_port = 9150
network.proxy.socks_remote_dns = true
network.proxy.type = 1 //Manual proxy configuration
Result: DNS Leaks

Case 14 - confirmed
network.proxy.socks = localhost
network.proxy.socks_port = 9150
network.proxy.socks_remote_dns = true
network.proxy.type = 2 //Automatic proxy configuration URL
Result: DNS Leaks

Case 15 - confirmed
network.proxy.socks = localhost
network.proxy.socks_port = 9150
network.proxy.socks_remote_dns = true
network.proxy.type = 4 //Auto-detect proxy settings for this network
Result: DNS Leaks

Release (107.0/20221110173214)
Case 6 - confirmed
network.proxy.socks_remote_dns = true //Proxy DNS when using SOCKS v5
network.proxy.type = 5 //Use system proxy settings (Default value)
Result: DNS Leaks

Case 7 - confirmed
network.proxy.socks_remote_dns = true
network.proxy.type = 0 //No proxy
Result: DNS Leaks

Case 8 - confirmed
network.proxy.socks_remote_dns = true
network.proxy.type = 1 //Manual proxy configuration
Result: DNS Leaks

Case 9 - confirmed
network.proxy.socks_remote_dns = true
network.proxy.type = 2 //Automatic proxy configuration URL
Result: DNS Leaks

Case 10 - confirmed
network.proxy.socks_remote_dns = true
network.proxy.type = 4 //Auto-detect proxy settings for this network
Result: DNS Leaks

Case 11 - confirmed
network.proxy.socks = localhost
network.proxy.socks_port = 9150
network.proxy.socks_remote_dns = true
network.proxy.type = 5 //Use system proxy settings (Default value)
Result: DNS Leaks

Case 12 - confirmed
network.proxy.socks = localhost
network.proxy.socks_port = 9150
network.proxy.socks_remote_dns = true
network.proxy.type = 0 //No proxy
Result: DNS Leaks

Case 13 - I get DNS leak according to surfshark.com/dns-leak-test, however the list produced by the website check was much much smaller (2 IP addresses only as opposed to around 9 to 10 in the other cases) so I don’t really know if this counts as a leak or not.
network.proxy.socks = localhost
network.proxy.socks_port = 9150
network.proxy.socks_remote_dns = true
network.proxy.type = 1 //Manual proxy configuration
Result: DNS Leaks

Case 14 - confirmed
network.proxy.socks = localhost
network.proxy.socks_port = 9150
network.proxy.socks_remote_dns = true
network.proxy.type = 2 //Automatic proxy configuration URL
Result: DNS Leaks

Case 15 - confirmed
network.proxy.socks = localhost
network.proxy.socks_port = 9150
network.proxy.socks_remote_dns = true
network.proxy.type = 4 //Auto-detect proxy settings for this network
Result: DNS Leaks

The only inconsistency I found is with Case 13, where you specified that there is no DNS leak, but on my end, according to surfshark.com, there is a DNS leak.
I will refrain for the moment to change the status of the bug, until confirmation that the results I obtained are indeed the correct ones. Thank you !

(In reply to Alex Cornestean from comment #14)

Case 13 - I get DNS leak according to surfshark.com/dns-leak-test, however the list produced by the website check was much much smaller (2 IP addresses only as opposed to around 9 to 10 in the other cases) so I don’t really know if this counts as a leak or not.

I use the command sudo tcpdump udp port 53 to confirm whether there are DNS requests on my Linux laptop. Wireshark with DNS packet filter also could work for the other platform. DNS leak test website is a simple way to generate many random DNS in a short time, surfshark's result is for reference only.

Please note Bug 1791243 which shows that the DNS leak is not a "proxy extension" issue but a Firefox proxy issue (can be tested without any extension).

Based on Comment 16 (that the issue can be reproduced without an extension as well, resulting it's not a Webextensions issue) and the so far obtained results, I’ll change the status to New and update the component/product of the report to be more accurate. Please revert the changes in case of error. Thank you !

Status: UNCONFIRMED → NEW
Component: General → Networking: DNS
Ever confirmed: true
Product: WebExtensions → Core
Version: Firefox 106 → Firefox 109

Moving back to WebExtensions for further discussion. While the dns.resolve extension API triggers the reported leak, I'd like to have a more general consensus on how proxy extensions are supposed to register proxies with the intent of capturing all traffic (comment 9).

After that discussion we may move this bug or a new dependency back to the networking component if needed.

Component: Networking: DNS → General
Product: Core → WebExtensions

There is a lot in this bug that is confusing.

proxy.socks_remote_dns = true will only work if proxy.type = 1 and you have a working socks 5 proxy.

Why is any other proxy.type setting considered to be a dns leak? Can anyone explain the specific bug here in terms of how the proxy prefs actually work? e.g. Confirming a "leak" when proxy.type = 0 is incorrect regardless of other settings.

(In reply to Shane Caraveo (:mixedpuppy) from comment #19)

There is a lot in this bug that is confusing.

proxy.socks_remote_dns = true will only work if proxy.type = 1 and you have a working socks 5 proxy.

Why is any other proxy.type setting considered to be a dns leak? Can anyone explain the specific bug here in terms of how the proxy prefs actually work? e.g. Confirming a "leak" when proxy.type = 0 is incorrect regardless of other settings.

This bug is specified to proxy.onRequest. I can see many people complain they use VPN/Proxy extension with uBlock Origin has DNS leak [1, 2].

The interesting is some prefs can prevent this lesk happened. Why? Because bug 1618271's patch disable the dns when 1) manual proxy configuration 2) has socks proxy and port 3) setting proxy dns. (See Rob's first link)

The severity field is not set for this bug.
:willdurand, could you have a look please?

For more information, please visit auto_nag documentation.

Flags: needinfo?(wdurand)
Flags: needinfo?(wdurand)
See Also: → 1812360
Severity: -- → S3
Priority: -- → P3
You need to log in before you can comment on or make changes to this bug.