- Revision
- 194323
- Author
- mcatanz...@igalia.com
- Date
- 2015-12-20 17:19:41 -0800 (Sun, 20 Dec 2015)
Log Message
[SOUP] Performs DNS prefetch when a proxy is configured (information leak)
https://bugs.webkit.org/show_bug.cgi?id=145542
Reviewed by Darin Adler.
Source/WebCore:
Perform DNS prefetch only when no proxy is configured.
No new tests. Test this manually with Wireshark. Run the simple-proxy example program found
in libsoup's examples directory, set that as your system HTTP proxy, and see if DNS queries
show up in Wireshark when refreshing a page sent over HTTP. They should appear only when the
proxy is not configured.
* platform/network/DNSResolveQueue.cpp:
(WebCore::DNSResolveQueue::DNSResolveQueue):
(WebCore::DNSResolveQueue::isUsingProxy):
* platform/network/DNSResolveQueue.h:
* platform/network/cf/DNSCFNet.cpp:
(WebCore::DNSResolveQueue::updateIsUsingProxy):
(WebCore::DNSResolveQueue::platformProxyIsEnabledInSystemPreferences): Deleted.
* platform/network/soup/DNSSoup.cpp:
(WebCore::didResolveProxy):
(WebCore::proxyResolvedForHttpUriCallback):
(WebCore::proxyResolvedForHttpsUriCallback):
(WebCore::DNSResolveQueue::updateIsUsingProxy):
(WebCore::DNSResolveQueue::platformProxyIsEnabledInSystemPreferences): Deleted.
Source/WTF:
Specialize GUniquePtr<char*>, using g_strfreev.
* wtf/glib/GUniquePtr.h:
Modified Paths
Diff
Modified: trunk/Source/WTF/ChangeLog (194322 => 194323)
--- trunk/Source/WTF/ChangeLog 2015-12-20 21:57:01 UTC (rev 194322)
+++ trunk/Source/WTF/ChangeLog 2015-12-21 01:19:41 UTC (rev 194323)
@@ -1,3 +1,14 @@
+2015-12-20 Michael Catanzaro <mcatanz...@igalia.com>
+
+ [SOUP] Performs DNS prefetch when a proxy is configured (information leak)
+ https://bugs.webkit.org/show_bug.cgi?id=145542
+
+ Reviewed by Darin Adler.
+
+ Specialize GUniquePtr<char*>, using g_strfreev.
+
+ * wtf/glib/GUniquePtr.h:
+
2015-12-19 Dan Bernstein <m...@apple.com>
[Mac] WebKit contains dead source code for OS X Mavericks and earlier
Modified: trunk/Source/WTF/wtf/glib/GUniquePtr.h (194322 => 194323)
--- trunk/Source/WTF/wtf/glib/GUniquePtr.h 2015-12-20 21:57:01 UTC (rev 194322)
+++ trunk/Source/WTF/wtf/glib/GUniquePtr.h 2015-12-21 01:19:41 UTC (rev 194323)
@@ -43,7 +43,8 @@
macro(GPatternSpec, g_pattern_spec_free) \
macro(GDir, g_dir_close) \
macro(GTimer, g_timer_destroy) \
- macro(GKeyFile, g_key_file_free)
+ macro(GKeyFile, g_key_file_free) \
+ macro(char*, g_strfreev)
#define WTF_DEFINE_GPTR_DELETER(typeName, deleterFunc) \
template<> struct GPtrDeleter<typeName> \
Modified: trunk/Source/WebCore/ChangeLog (194322 => 194323)
--- trunk/Source/WebCore/ChangeLog 2015-12-20 21:57:01 UTC (rev 194322)
+++ trunk/Source/WebCore/ChangeLog 2015-12-21 01:19:41 UTC (rev 194323)
@@ -1,3 +1,31 @@
+2015-12-20 Michael Catanzaro <mcatanz...@igalia.com>
+
+ [SOUP] Performs DNS prefetch when a proxy is configured (information leak)
+ https://bugs.webkit.org/show_bug.cgi?id=145542
+
+ Reviewed by Darin Adler.
+
+ Perform DNS prefetch only when no proxy is configured.
+
+ No new tests. Test this manually with Wireshark. Run the simple-proxy example program found
+ in libsoup's examples directory, set that as your system HTTP proxy, and see if DNS queries
+ show up in Wireshark when refreshing a page sent over HTTP. They should appear only when the
+ proxy is not configured.
+
+ * platform/network/DNSResolveQueue.cpp:
+ (WebCore::DNSResolveQueue::DNSResolveQueue):
+ (WebCore::DNSResolveQueue::isUsingProxy):
+ * platform/network/DNSResolveQueue.h:
+ * platform/network/cf/DNSCFNet.cpp:
+ (WebCore::DNSResolveQueue::updateIsUsingProxy):
+ (WebCore::DNSResolveQueue::platformProxyIsEnabledInSystemPreferences): Deleted.
+ * platform/network/soup/DNSSoup.cpp:
+ (WebCore::didResolveProxy):
+ (WebCore::proxyResolvedForHttpUriCallback):
+ (WebCore::proxyResolvedForHttpsUriCallback):
+ (WebCore::DNSResolveQueue::updateIsUsingProxy):
+ (WebCore::DNSResolveQueue::platformProxyIsEnabledInSystemPreferences): Deleted.
+
2015-12-20 Dan Bernstein <m...@apple.com>
Remove unused setToolbarHeight
Modified: trunk/Source/WebCore/platform/network/DNSResolveQueue.cpp (194322 => 194323)
--- trunk/Source/WebCore/platform/network/DNSResolveQueue.cpp 2015-12-20 21:57:01 UTC (rev 194322)
+++ trunk/Source/WebCore/platform/network/DNSResolveQueue.cpp 2015-12-21 01:19:41 UTC (rev 194323)
@@ -60,20 +60,27 @@
DNSResolveQueue::DNSResolveQueue()
: m_timer(*this, &DNSResolveQueue::timerFired)
, m_requestsInFlight(0)
- , m_cachedProxyEnabledStatus(false)
+ , m_isUsingProxy(true)
, m_lastProxyEnabledStatusCheckTime(0)
{
+ // isUsingProxy will return the initial value of m_isUsingProxy at first on
+ // platforms that have an asynchronous implementation of updateIsUsingProxy,
+ // so initialize it to true so we won't prefetch before we know if we are using a proxy.
}
+// Don't do DNS prefetch if proxies are involved. For many proxy types, the user agent is never
+// exposed to the IP address during normal operation. Querying an internal DNS server may not help
+// performance, as it doesn't necessarily look up the actual external IP. Also, if DNS returns a
+// fake internal address, local caches may keep it even after re-connecting to another network.
bool DNSResolveQueue::isUsingProxy()
{
double time = monotonicallyIncreasingTime();
static const double minimumProxyCheckDelay = 5;
if (time - m_lastProxyEnabledStatusCheckTime > minimumProxyCheckDelay) {
m_lastProxyEnabledStatusCheckTime = time;
- m_cachedProxyEnabledStatus = platformProxyIsEnabledInSystemPreferences();
+ updateIsUsingProxy();
}
- return m_cachedProxyEnabledStatus;
+ return m_isUsingProxy;
}
void DNSResolveQueue::add(const String& hostname)
Modified: trunk/Source/WebCore/platform/network/DNSResolveQueue.h (194322 => 194323)
--- trunk/Source/WebCore/platform/network/DNSResolveQueue.h 2015-12-20 21:57:01 UTC (rev 194322)
+++ trunk/Source/WebCore/platform/network/DNSResolveQueue.h 2015-12-21 01:19:41 UTC (rev 194323)
@@ -52,7 +52,7 @@
bool isUsingProxy();
- bool platformProxyIsEnabledInSystemPreferences();
+ void updateIsUsingProxy();
void platformResolve(const String&);
void timerFired();
@@ -61,7 +61,7 @@
HashSet<String> m_names;
std::atomic<int> m_requestsInFlight;
- bool m_cachedProxyEnabledStatus;
+ bool m_isUsingProxy;
double m_lastProxyEnabledStatusCheckTime;
};
Modified: trunk/Source/WebCore/platform/network/cf/DNSCFNet.cpp (194322 => 194323)
--- trunk/Source/WebCore/platform/network/cf/DNSCFNet.cpp 2015-12-20 21:57:01 UTC (rev 194322)
+++ trunk/Source/WebCore/platform/network/cf/DNSCFNet.cpp 2015-12-21 01:19:41 UTC (rev 194323)
@@ -48,16 +48,13 @@
namespace WebCore {
-bool DNSResolveQueue::platformProxyIsEnabledInSystemPreferences()
+void DNSResolveQueue::updateIsUsingProxy()
{
- // Don't do DNS prefetch if proxies are involved. For many proxy types, the user agent is never exposed
- // to the IP address during normal operation. Querying an internal DNS server may not help performance,
- // as it doesn't necessarily look up the actual external IP. Also, if DNS returns a fake internal address,
- // local caches may keep it even after re-connecting to another network.
-
RetainPtr<CFDictionaryRef> proxySettings = adoptCF(CFNetworkCopySystemProxySettings());
- if (!proxySettings)
- return false;
+ if (!proxySettings) {
+ m_isUsingProxy = false;
+ return;
+ }
RetainPtr<CFURLRef> httpCFURL = URL(ParsedURLString, "http://example.com/").createCFURL();
RetainPtr<CFURLRef> httpsCFURL = URL(ParsedURLString, "https://example.com/").createCFURL();
@@ -72,7 +69,7 @@
if (httpsProxyCount == 1 && CFEqual(CFDictionaryGetValue(static_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(httpsProxyArray.get(), 0)), kCFProxyTypeKey), kCFProxyTypeNone))
httpsProxyCount = 0;
- return httpProxyCount || httpsProxyCount;
+ m_isUsingProxy = httpProxyCount || httpsProxyCount;
}
static void clientCallback(CFHostRef theHost, CFHostInfoType, const CFStreamError*, void*)
Modified: trunk/Source/WebCore/platform/network/soup/DNSSoup.cpp (194322 => 194323)
--- trunk/Source/WebCore/platform/network/soup/DNSSoup.cpp 2015-12-20 21:57:01 UTC (rev 194322)
+++ trunk/Source/WebCore/platform/network/soup/DNSSoup.cpp 2015-12-21 01:19:41 UTC (rev 194323)
@@ -33,18 +33,58 @@
#include "SoupNetworkSession.h"
#include <libsoup/soup.h>
#include <wtf/MainThread.h>
+#include <wtf/glib/GUniquePtr.h>
#include <wtf/text/CString.h>
namespace WebCore {
-// There is no current reliable way to know if we're behind a proxy at
-// this level. We'll have to implement it in
-// SoupSession/SoupProxyURIResolver/GProxyResolver
-bool DNSResolveQueue::platformProxyIsEnabledInSystemPreferences()
+// Initially true to ensure prefetch stays disabled until we have proxy settings.
+static bool isUsingHttpProxy = true;
+static bool isUsingHttpsProxy = true;
+
+static bool didResolveProxy(char** uris)
{
- return false;
+ // We have a list of possible proxies to use for the URI. If the first item in the list is
+ // direct:// (the usual case), then the user prefers not to use a proxy. This is similar to
+ // resolving hostnames: there could be many possibilities returned in order of preference, and
+ // if we're trying to connect we should attempt each one in order, but here we are not trying
+ // to connect, merely to decide whether a proxy "should" be used.
+ return uris && *uris && strcmp(*uris, "direct://");
}
+static void didResolveProxy(GProxyResolver* resolver, GAsyncResult* result, bool* isUsingProxyType, bool* isUsingProxy)
+{
+ GUniqueOutPtr<GError> error;
+ GUniquePtr<char*> uris(g_proxy_resolver_lookup_finish(resolver, result, &error.outPtr()));
+ if (error) {
+ WTFLogAlways("Error determining system proxy settings: %s", error->message);
+ return;
+ }
+
+ *isUsingProxyType = didResolveProxy(uris.get());
+ *isUsingProxy = isUsingHttpProxy || isUsingHttpsProxy;
+}
+
+static void proxyResolvedForHttpUriCallback(GObject* source, GAsyncResult* result, void* userData)
+{
+ didResolveProxy(G_PROXY_RESOLVER(source), result, &isUsingHttpProxy, static_cast<bool*>(userData));
+}
+
+static void proxyResolvedForHttpsUriCallback(GObject* source, GAsyncResult* result, void* userData)
+{
+ didResolveProxy(G_PROXY_RESOLVER(source), result, &isUsingHttpsProxy, static_cast<bool*>(userData));
+}
+
+void DNSResolveQueue::updateIsUsingProxy()
+{
+ GRefPtr<GProxyResolver> resolver;
+ g_object_get(SoupNetworkSession::defaultSession().soupSession(), "proxy-resolver", &resolver.outPtr(), nullptr);
+ ASSERT(resolver);
+
+ g_proxy_resolver_lookup_async(resolver.get(), "http://example.com/", nullptr, proxyResolvedForHttpUriCallback, &m_isUsingProxy);
+ g_proxy_resolver_lookup_async(resolver.get(), "https://example.com/", nullptr, proxyResolvedForHttpsUriCallback, &m_isUsingProxy);
+}
+
static void resolvedCallback(SoupAddress*, guint, void*)
{
DNSResolveQueue::singleton().decrementRequestCount();