Skip to content
Snippets Groups Projects
Commit 177e7892 authored by Mike Perry's avatar Mike Perry Committed by Georg Koppen
Browse files

Bug #5741: Prevent WebSocket DNS leak.

This is due to an improper implementation of the WebSocket spec by Mozilla.

"There MUST be no more than one connection in a CONNECTING state.  If multiple
connections to the same IP address are attempted simultaneously, the client
MUST serialize them so that there is no more than one connection at a time
running through the following steps.

If the client cannot determine the IP address of the remote host (for
example, because all communication is being done through a proxy server that
performs DNS queries itself), then the client MUST assume for the purposes of
this step that each host name refers to a distinct remote host,"

https://tools.ietf.org/html/rfc6455#page-15

They implmented the first paragraph, but not the second...

While we're at it, we also prevent the DNS service from being used to look up
anything other than IP addresses if socks_remote_dns is set to true, so this
bug can't turn up in other components or due to 3rd party addons.
parent 476cc1f0
No related merge requests found
......@@ -544,6 +544,7 @@ nsDNSService::Init()
bool disableIPv6 = false;
bool offlineLocalhost = true;
bool disablePrefetch = false;
bool disableDNS = false;
bool blockDotOnion = true;
int proxyType = nsIProtocolProxyService::PROXYCONFIG_DIRECT;
bool notifyResolution = false;
......@@ -572,6 +573,11 @@ nsDNSService::Init()
// If a manual proxy is in use, disable prefetch implicitly
prefs->GetIntPref("network.proxy.type", &proxyType);
// If the user wants remote DNS, we should fail any lookups that still
// make it here.
prefs->GetBoolPref("network.proxy.socks_remote_dns", &disableDNS);
prefs->GetBoolPref(kPrefDnsNotifyResolution, &notifyResolution);
}
......@@ -593,7 +599,7 @@ nsDNSService::Init()
// Monitor these to see if there is a change in proxy configuration
// If a manual proxy is in use, disable prefetch implicitly
prefs->AddObserver("network.proxy.type", this, false);
prefs->AddObserver("network.proxy.", this, false);
}
nsCOMPtr<nsIObserverService> observerService =
......@@ -622,6 +628,7 @@ nsDNSService::Init()
mIPv4OnlyDomains = ipv4OnlyDomains; // exchanges buffer ownership
mOfflineLocalhost = offlineLocalhost;
mDisableIPv6 = disableIPv6;
mDisableDNS = disableDNS;
mBlockDotOnion = blockDotOnion;
// Disable prefetching either by explicit preference or if a manual proxy is configured
......@@ -771,6 +778,14 @@ nsDNSService::AsyncResolveExtended(const nsACString &aHostname,
NS_DispatchToMainThread(new NotifyDNSResolution(aHostname));
}
PRNetAddr tempAddr;
if (mDisableDNS) {
// Allow IP lookups through, but nothing else.
if (PR_StringToNetAddr(aHostname.BeginReading(), &tempAddr) != PR_SUCCESS) {
return NS_ERROR_UNKNOWN_PROXY_HOST; // XXX: NS_ERROR_NOT_IMPLEMENTED?
}
}
if (!res)
return NS_ERROR_OFFLINE;
......@@ -900,6 +915,14 @@ nsDNSService::Resolve(const nsACString &aHostname,
flags |= RESOLVE_OFFLINE;
}
PRNetAddr tempAddr;
if (mDisableDNS) {
// Allow IP lookups through, but nothing else.
if (PR_StringToNetAddr(aHostname.BeginReading(), &tempAddr) != PR_SUCCESS) {
return NS_ERROR_UNKNOWN_PROXY_HOST; // XXX: NS_ERROR_NOT_IMPLEMENTED?
}
}
//
// sync resolve: since the host resolver only works asynchronously, we need
// to use a mutex and a condvar to wait for the result. however, since the
......
......
......@@ -62,6 +62,7 @@ private:
bool mDisablePrefetch;
bool mBlockDotOnion;
bool mFirstTime;
bool mDisableDNS;
bool mOffline;
bool mNotifyResolution;
bool mOfflineLocalhost;
......
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment