Title: [194323] trunk/Source
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();
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to