Changeset 185320 in webkit


Ignore:
Timestamp:
Jun 8, 2015 9:17:39 AM (9 years ago)
Author:
Michael Catanzaro
Message:

[SOUP] Performs DNS prefetch when a proxy is configured (information leak)
https://bugs.webkit.org/show_bug.cgi?id=145542

Reviewed by Alexey Proskuryakov.

Source/WebCore:

No new tests, because it's hard to test whether a DNS request has been sent. We could do
this by adding new API to modify the GProxyResolver and GResolver used by the SoupSession in
the network process, but even if such API were desirable, it would be a big job. Tests
should not be allowed to dictate our public API.

  • platform/network/DNSResolveQueue.cpp:

(WebCore::DNSResolveQueue::add): Do not check whether the system is using a proxy, since
this can't be determined for all ports here.
(WebCore::DNSResolveQueue::timerFired): Do not check whether the system is using a proxy,
since this can't be determined for all ports here.
(WebCore::DNSResolveQueue::DNSResolveQueue): Remove member variables and member functions
that are only needed by the CF backend. Rename platformResolve to
platformMaybeResolveHost.
(WebCore::DNSResolveQueue::isUsingProxy): Moved to DNSCFNet.cpp.

  • platform/network/DNSResolveQueue.h: Remove member variables that are only needed by the

CF backend.

  • platform/network/cf/DNSCFNet.cpp:

(WebCore::proxyIsEnabledInSystemPreferences): Renamed from
platformProxyIsEnabledInSystemPreferences.
(WebCore::isUsingProxy): Moved from DNSResolveQueue.cpp. The member variables removed from
DNSResolveQueue are not static here. This is safe since it's a singleton.
(WebCore::DNSResolveQueue::platformMaybeResolveHost): Renamed from platformResolve.
Bail early from here if a proxy is configured.
(WebCore::DNSResolveQueue::platformProxyIsEnabledInSystemPreferences): Renamed to
proxyIsEnabledInSystemPreferences.
(WebCore::DNSResolveQueue::platformResolve): Renamed to platformMaybeResolveHost.

  • platform/network/soup/DNSSoup.cpp:

(WebCore::gotProxySettingsCallback): Added. Call soup_session_prefetch_dns from here only
if a proxy would not be used to resolve the host.
(WebCore::DNSResolveQueue::platformMaybeResolveHost): Renamed from platformResolve.
Look up proxy settings using g_proxy_resolver_lookup_async rather than calling
soup_session_prefetch_dns directly.
(WebCore::DNSResolveQueue::platformProxyIsEnabledInSystemPreferences): Deleted.
(WebCore::DNSResolveQueue::platformResolve): Renamed to platformMaybeResolveHost.

Source/WebKit2:

Add documentation to webkit_web_context_prefetch_dns to indicate that the function does
nothing if the system configuration indicates we should use a proxy to resolve the host.

  • UIProcess/API/gtk/WebKitWebContext.cpp:

Source/WTF:

Add template specialization for GUniquePtr<char*>. This smart pointer will free its data
with g_strfreev() (as opposed to g_free(), which is used for GUniquePtr<char>).

  • wtf/gobject/GUniquePtr.h:
Location:
trunk/Source
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WTF/ChangeLog

    r185303 r185320  
     12015-06-08  Michael Catanzaro  <mcatanzaro@igalia.com>
     2
     3        [SOUP] Performs DNS prefetch when a proxy is configured (information leak)
     4        https://bugs.webkit.org/show_bug.cgi?id=145542
     5
     6        Reviewed by Alexey Proskuryakov.
     7
     8        Add template specialization for GUniquePtr<char*>. This smart pointer will free its data
     9        with g_strfreev() (as opposed to g_free(), which is used for GUniquePtr<char>).
     10
     11        * wtf/gobject/GUniquePtr.h:
     12
    1132015-06-05  Chris Dumez  <cdumez@apple.com>
    214
  • trunk/Source/WTF/wtf/gobject/GUniquePtr.h

    r163797 r185320  
    4444    macro(GDir, g_dir_close) \
    4545    macro(GTimer, g_timer_destroy) \
    46     macro(GKeyFile, g_key_file_free)
     46    macro(GKeyFile, g_key_file_free) \
     47    macro(char*, g_strfreev)
    4748
    4849#define WTF_DEFINE_GPTR_DELETER(typeName, deleterFunc) \
  • trunk/Source/WebCore/ChangeLog

    r185316 r185320  
     12015-06-08  Michael Catanzaro  <mcatanzaro@igalia.com>
     2
     3        [SOUP] Performs DNS prefetch when a proxy is configured (information leak)
     4        https://bugs.webkit.org/show_bug.cgi?id=145542
     5
     6        Reviewed by Alexey Proskuryakov.
     7
     8        No new tests, because it's hard to test whether a DNS request has been sent. We could do
     9        this by adding new API to modify the GProxyResolver and GResolver used by the SoupSession in
     10        the network process, but even if such API were desirable, it would be a big job. Tests
     11        should not be allowed to dictate our public API.
     12
     13        * platform/network/DNSResolveQueue.cpp:
     14        (WebCore::DNSResolveQueue::add): Do not check whether the system is using a proxy, since
     15        this can't be determined for all ports here.
     16        (WebCore::DNSResolveQueue::timerFired): Do not check whether the system is using a proxy,
     17        since this can't be determined for all ports here.
     18        (WebCore::DNSResolveQueue::DNSResolveQueue): Remove member variables and member functions
     19        that are only needed by the CF backend. Rename platformResolve to
     20        platformMaybeResolveHost.
     21        (WebCore::DNSResolveQueue::isUsingProxy): Moved to DNSCFNet.cpp.
     22        * platform/network/DNSResolveQueue.h: Remove member variables that are only needed by the
     23        CF backend.
     24        * platform/network/cf/DNSCFNet.cpp:
     25        (WebCore::proxyIsEnabledInSystemPreferences): Renamed from
     26        platformProxyIsEnabledInSystemPreferences.
     27        (WebCore::isUsingProxy): Moved from DNSResolveQueue.cpp. The member variables removed from
     28        DNSResolveQueue are not static here. This is safe since it's a singleton.
     29        (WebCore::DNSResolveQueue::platformMaybeResolveHost): Renamed from platformResolve.
     30        Bail early from here if a proxy is configured.
     31        (WebCore::DNSResolveQueue::platformProxyIsEnabledInSystemPreferences): Renamed to
     32        proxyIsEnabledInSystemPreferences.
     33        (WebCore::DNSResolveQueue::platformResolve): Renamed to platformMaybeResolveHost.
     34        * platform/network/soup/DNSSoup.cpp:
     35        (WebCore::gotProxySettingsCallback): Added. Call soup_session_prefetch_dns from here only
     36        if a proxy would not be used to resolve the host.
     37        (WebCore::DNSResolveQueue::platformMaybeResolveHost): Renamed from platformResolve.
     38        Look up proxy settings using g_proxy_resolver_lookup_async rather than calling
     39        soup_session_prefetch_dns directly.
     40        (WebCore::DNSResolveQueue::platformProxyIsEnabledInSystemPreferences): Deleted.
     41        (WebCore::DNSResolveQueue::platformResolve): Renamed to platformMaybeResolveHost.
     42
    1432015-06-08  Hunseop Jeong  <hs85.jeong@samsung.com>
    244
  • trunk/Source/WebCore/platform/network/DNSResolveQueue.cpp

    r179409 r185320  
    2828#include "DNSResolveQueue.h"
    2929
    30 #include <wtf/CurrentTime.h>
    3130#include <wtf/NeverDestroyed.h>
    3231
     
    6160    : m_timer(*this, &DNSResolveQueue::timerFired)
    6261    , m_requestsInFlight(0)
    63     , m_cachedProxyEnabledStatus(false)
    64     , m_lastProxyEnabledStatusCheckTime(0)
    6562{
    66 }
    67 
    68 bool DNSResolveQueue::isUsingProxy()
    69 {
    70     double time = monotonicallyIncreasingTime();
    71     static const double minimumProxyCheckDelay = 5;
    72     if (time - m_lastProxyEnabledStatusCheckTime > minimumProxyCheckDelay) {
    73         m_lastProxyEnabledStatusCheckTime = time;
    74         m_cachedProxyEnabledStatus = platformProxyIsEnabledInSystemPreferences();
    75     }
    76     return m_cachedProxyEnabledStatus;
    7763}
    7864
     
    8167    // If there are no names queued, and few enough are in flight, resolve immediately (the mouse may be over a link).
    8268    if (!m_names.size()) {
    83         if (isUsingProxy())
    84             return;
    8569        if (++m_requestsInFlight <= gNamesToResolveImmediately) {
    86             platformResolve(hostname);
     70            platformMaybeResolveHost(hostname);
    8771            return;
    8872        }
     
    10185void DNSResolveQueue::timerFired()
    10286{
    103     if (isUsingProxy()) {
    104         m_names.clear();
    105         return;
    106     }
    107 
    10887    int requestsAllowed = gMaxSimultaneousRequests - m_requestsInFlight;
    10988
     
    11190        ++m_requestsInFlight;
    11291        HashSet<String>::iterator currentName = m_names.begin();
    113         platformResolve(*currentName);
     92        platformMaybeResolveHost(*currentName);
    11493        m_names.remove(currentName);
    11594    }
  • trunk/Source/WebCore/platform/network/DNSResolveQueue.h

    r179409 r185320  
    5151    DNSResolveQueue();
    5252
    53     bool isUsingProxy();
    54 
    55     bool platformProxyIsEnabledInSystemPreferences();
    56     void platformResolve(const String&);
     53    // This function performs the actual DNS prefetch. Platforms must ensure that performing the
     54    // prefetch will not violate the user's expectations of privacy; for example, if an HTTP proxy
     55    // is in use, then performing a DNS lookup would be inappropriate, but this may be acceptable
     56    // for other types of proxies (e.g. SOCKS proxies).
     57    void platformMaybeResolveHost(const String&);
    5758
    5859    void timerFired();
     
    6263    HashSet<String> m_names;
    6364    std::atomic<int> m_requestsInFlight;
    64     bool m_cachedProxyEnabledStatus;
    65     double m_lastProxyEnabledStatusCheckTime;
    6665};
    6766
  • trunk/Source/WebCore/platform/network/cf/DNSCFNet.cpp

    r179409 r185320  
    3232#include "URL.h"
    3333#include "Timer.h"
     34#include <wtf/CurrentTime.h>
    3435#include <wtf/HashSet.h>
    3536#include <wtf/MainThread.h>
     
    4950namespace WebCore {
    5051
    51 bool DNSResolveQueue::platformProxyIsEnabledInSystemPreferences()
     52static bool proxyIsEnabledInSystemPreferences()
    5253{
    5354    // Don't do DNS prefetch if proxies are involved. For many proxy types, the user agent is never exposed
     
    7677}
    7778
     79static bool isUsingProxy()
     80{
     81    static bool cachedProxyEnabledStatus = false;
     82    static double lastProxyEnabledStatusCheckTime = 0;
     83    static const double minimumProxyCheckDelay = 5;
     84    double time = monotonicallyIncreasingTime();
     85    if (time - lastProxyEnabledStatusCheckTime > minimumProxyCheckDelay) {
     86        lastProxyEnabledStatusCheckTime = time;
     87        cachedProxyEnabledStatus = proxyIsEnabledInSystemPreferences();
     88    }
     89    return cachedProxyEnabledStatus;
     90}
     91
    7892static void clientCallback(CFHostRef theHost, CFHostInfoType, const CFStreamError*, void*)
    7993{
     
    8296}
    8397
    84 void DNSResolveQueue::platformResolve(const String& hostname)
     98void DNSResolveQueue::platformMaybeResolveHost(const String& hostname)
    8599{
    86100    ASSERT(isMainThread());
    87101
    88102    RetainPtr<CFHostRef> host = adoptCF(CFHostCreateWithName(0, hostname.createCFString().get()));
    89     if (!host) {
     103    if (!host || isUsingProxy()) {
    90104        decrementRequestCount();
    91105        return;
  • trunk/Source/WebCore/platform/network/soup/DNSSoup.cpp

    r179409 r185320  
    11/*
    22 * Copyright (C) 2008 Apple Inc.  All rights reserved.
    3  * Copyright (C) 2009, 2012 Igalia S.L.
     3 * Copyright (C) 2009, 2012, 2015 Igalia S.L.
    44 *
    55 * Redistribution and use in source and binary forms, with or without
     
    3434#include <libsoup/soup.h>
    3535#include <wtf/MainThread.h>
     36#include <wtf/gobject/GRefPtr.h>
     37#include <wtf/gobject/GUniquePtr.h>
    3638#include <wtf/text/CString.h>
    3739
    3840namespace WebCore {
    3941
    40 // There is no current reliable way to know if we're behind a proxy at
    41 // this level. We'll have to implement it in
    42 // SoupSession/SoupProxyURIResolver/GProxyResolver
    43 bool DNSResolveQueue::platformProxyIsEnabledInSystemPreferences()
     42static void gotProxySettingsCallback(GObject* sourceObject, GAsyncResult* result, void* userData)
    4443{
    45     return false;
     44    GProxyResolver* resolver = G_PROXY_RESOLVER(sourceObject);
     45    GUniquePtr<char> hostname(static_cast<char*>(userData));
     46    GUniqueOutPtr<GError> error;
     47
     48    GUniquePtr<char*> uris(g_proxy_resolver_lookup_finish(resolver, result, &error.outPtr()));
     49    if (error) {
     50        WTFLogAlways("Error determining proxy to use for %s: %s", hostname.get(), error->message);
     51        return;
     52    }
     53
     54    // We have a list of possible proxies to use for the URI. If the first item in the list is
     55    // direct:// (the usual case), then the user prefers not to use a proxy. This is similar to
     56    // resolving hostnames: there could be many possibilities returned in order of preference, and
     57    // if we're trying to connect we should attempt each one in order, but here we are not trying
     58    // to connect, merely to decide whether a proxy "should" be used.
     59    if (uris && *uris.get() && !strcmp(*uris.get(), "direct://")) {
     60        soup_session_prefetch_dns(SoupNetworkSession::defaultSession().soupSession(), hostname.get(), nullptr, [](SoupAddress*, guint, void*) {
     61            DNSResolveQueue::singleton().decrementRequestCount();
     62        }, nullptr);
     63    }
    4664}
    4765
    48 static void resolvedCallback(SoupAddress*, guint, void*)
    49 {
    50     DNSResolveQueue::singleton().decrementRequestCount();
    51 }
    52 
    53 void DNSResolveQueue::platformResolve(const String& hostname)
     66void DNSResolveQueue::platformMaybeResolveHost(const String& hostname)
    5467{
    5568    ASSERT(isMainThread());
    5669
    57     soup_session_prefetch_dns(SoupNetworkSession::defaultSession().soupSession(), hostname.utf8().data(), nullptr, resolvedCallback, nullptr);
     70    GRefPtr<GProxyResolver> resolver;
     71    g_object_get(SoupNetworkSession::defaultSession().soupSession(), "proxy-resolver", &resolver.outPtr(), nullptr);
     72    ASSERT_WITH_SECURITY_IMPLICATION(resolver);
     73
     74    char* uri = g_strdup(hostname.utf8().data()); // Freed by gotProxySettingsCallback.
     75    g_proxy_resolver_lookup_async(resolver.get(), uri, nullptr, gotProxySettingsCallback, uri);
    5876}
    5977
  • trunk/Source/WebKit2/ChangeLog

    r185317 r185320  
     12015-06-08  Michael Catanzaro  <mcatanzaro@igalia.com>
     2
     3        [SOUP] Performs DNS prefetch when a proxy is configured (information leak)
     4        https://bugs.webkit.org/show_bug.cgi?id=145542
     5
     6        Reviewed by Alexey Proskuryakov.
     7
     8        Add documentation to webkit_web_context_prefetch_dns to indicate that the function does
     9        nothing if the system configuration indicates we should use a proxy to resolve the host.
     10
     11        * UIProcess/API/gtk/WebKitWebContext.cpp:
     12
    1132015-06-08  Carlos Garcia Campos  <cgarcia@igalia.com>
    214
  • trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp

    r185311 r185320  
    10451045 *
    10461046 * Resolve the domain name of the given @hostname in advance, so that if a URI
    1047  * of @hostname is requested the load will be performed more quickly.
     1047 * of @hostname is requested the load will be performed more quickly. This
     1048 * function does nothing if the system has been configured to use a proxy to
     1049 * resolve @hostname.
    10481050 */
    10491051void webkit_web_context_prefetch_dns(WebKitWebContext* context, const char* hostname)
Note: See TracChangeset for help on using the changeset viewer.