Changeset 95747 in webkit


Ignore:
Timestamp:
Sep 22, 2011 12:41:00 PM (13 years ago)
Author:
ap@apple.com
Message:

[WK2] UIProcess should check that WebProcess isn't sending unexpected file: URLs to it
https://bugs.webkit.org/show_bug.cgi?id=68573

Reviewed by Anders Carlsson.

Re-landing with a slightly less aggressive check.

Location:
trunk/Source/WebKit2
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit2/ChangeLog

    r95715 r95747  
     12011-09-22  Alexey Proskuryakov  <ap@apple.com>
     2
     3        [WK2] UIProcess should check that WebProcess isn't sending unexpected file: URLs to it
     4        https://bugs.webkit.org/show_bug.cgi?id=68573
     5
     6        Reviewed by Anders Carlsson.
     7
     8        Re-landing with a slightly less aggressive check.
     9
     10        * UIProcess/API/mac/WKView.mm:
     11        (maybeCreateSandboxExtensionFromPasteboard): Return a boolean, telling the caller whether
     12        an extension actually needed to be created
     13        (-[WKView performDragOperation:]): Tell process proxy when the process is going to get
     14        universal file read sandbox extension.
     15
     16        * UIProcess/WebContext.cpp:
     17        (WebKit::WebContext::didPerformClientRedirect): Check the URLs.
     18        (WebKit::WebContext::didPerformServerRedirect): Ditto.
     19        (WebKit::WebContext::didUpdateHistoryTitle): Ditto.
     20        (WebKit::WebContext::getPluginPath): Ditto. Also, properly parse the URL - we can never
     21        assume that a string coming from WebProcess is a ParsedURLString.
     22
     23        * UIProcess/WebPageProxy.cpp:
     24        (WebKit::WebPageProxy::reattachToWebProcessWithItem): Tell process proxy when the process
     25        is going to get universal file read sandbox extension.
     26        (WebKit::WebPageProxy::maybeInitializeSandboxExtensionHandle): Changed to return a boolean,
     27        telling the caller whether an extension actually needed to be created.
     28        (WebKit::WebPageProxy::loadURL): Tell process proxy about extension.
     29        (WebKit::WebPageProxy::loadURLRequest): Ditto.
     30        (WebKit::WebPageProxy::loadHTMLString): Tell process proxy if a file URL was used as a base
     31        one for a string. In this case, WebKit2 assumes that WebProcess has access to a subdirectory,
     32        (typically, one where error page resources live), and can load from it.
     33        (WebKit::WebPageProxy::loadAlternateHTMLString): Ditto.
     34        (WebKit::WebPageProxy::goForward): Tell process proxy about extension.
     35        (WebKit::WebPageProxy::goBack): Tell process proxy about extension.
     36        (WebKit::WebPageProxy::goToBackForwardItem): Tell process proxy about extension.
     37        (WebKit::WebPageProxy::didStartProvisionalLoadForFrame): Check the URL.
     38        (WebKit::WebPageProxy::didReceiveServerRedirectForProvisionalLoadForFrame): Ditto.
     39        (WebKit::WebPageProxy::didSameDocumentNavigationForFrame): Ditto.
     40        (WebKit::WebPageProxy::decidePolicyForNavigationAction): Ditto.
     41        (WebKit::WebPageProxy::decidePolicyForNewWindowAction): Ditto.
     42        (WebKit::WebPageProxy::decidePolicyForResponse): Ditto.
     43        (WebKit::WebPageProxy::didInitiateLoadForResource): Ditto.
     44        (WebKit::WebPageProxy::didSendRequestForResource): Ditto.
     45        (WebKit::WebPageProxy::didReceiveResponseForResource): Ditto.
     46        (WebKit::WebPageProxy::missingPluginButtonClicked): Ditto.
     47
     48        * UIProcess/WebPageProxy.h: Changed initializeSandboxExtensionHandle() to return a bool,
     49        and renamed to maybeInitializeSandboxExtensionHandle (matching WKView counterpart).
     50
     51        * UIProcess/WebProcessProxy.cpp:
     52        (WebKit::WebProcessProxy::WebProcessProxy): Initialize m_mayHaveUniversalFileReadSandboxExtension.
     53        It's going to be true if we ever granted an extension for "/".
     54        (WebKit::WebProcessProxy::willLoadHTMLStringWithBaseURL): Remember the path, we should expect
     55        that WebProcess will load subresources from it.
     56        (WebKit::WebProcessProxy::checkURLReceivedFromWebProcess): Check that it's reasonable to expect
     57        WebProcess send us a URL like this.
     58        (WebKit::WebProcessProxy::addBackForwardItem): Check the URLs.
     59
     60        * UIProcess/WebProcessProxy.h: Added data members remembering what to expect from this process.
     61
     62        * UIProcess/cf/WebPageProxyCF.cpp: (WebKit::WebPageProxy::restoreFromSessionStateData):
     63        Tell process proxy when the process is going to get universal file read sandbox extension.
     64
    1652011-09-22  Alpha Lam  <hclam@chromium.org>
    266
  • trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm

    r95708 r95747  
    16611661// FIXME: This code is more or less copied from Pasteboard::getBestURL.
    16621662// It would be nice to be able to share the code somehow.
    1663 static void maybeCreateSandboxExtensionFromPasteboard(NSPasteboard *pasteboard, SandboxExtension::Handle& sandboxExtensionHandle)
     1663static bool maybeCreateSandboxExtensionFromPasteboard(NSPasteboard *pasteboard, SandboxExtension::Handle& sandboxExtensionHandle)
    16641664{
    16651665    NSArray *types = [pasteboard types];
    16661666    if (![types containsObject:NSFilenamesPboardType])
    1667         return;
     1667        return false;
    16681668
    16691669    NSArray *files = [pasteboard propertyListForType:NSFilenamesPboardType];
    16701670    if ([files count] != 1)
    1671         return;
     1671        return false;
    16721672
    16731673    NSString *file = [files objectAtIndex:0];
    16741674    BOOL isDirectory;
    16751675    if (![[NSFileManager defaultManager] fileExistsAtPath:file isDirectory:&isDirectory])
    1676         return;
     1676        return false;
    16771677
    16781678    if (isDirectory)
    1679         return;
     1679        return false;
    16801680
    16811681    SandboxExtension::createHandle("/", SandboxExtension::ReadOnly, sandboxExtensionHandle);
     1682    return true;
    16821683}
    16831684
     
    16891690
    16901691    SandboxExtension::Handle sandboxExtensionHandle;
    1691     maybeCreateSandboxExtensionFromPasteboard([draggingInfo draggingPasteboard], sandboxExtensionHandle);
     1692    bool createdExtension = maybeCreateSandboxExtensionFromPasteboard([draggingInfo draggingPasteboard], sandboxExtensionHandle);
     1693    if (createdExtension)
     1694        _data->_page->process()->willAcquireUniversalFileReadSandboxExtension();
    16921695
    16931696    _data->_page->performDrag(&dragData, [[draggingInfo draggingPasteboard] name], sandboxExtensionHandle);
  • trunk/Source/WebKit2/UIProcess/WebContext.cpp

    r95708 r95747  
    6666#endif
    6767
    68 #define MESSAGE_CHECK(assertion) MESSAGE_CHECK_BASE(assertion, process()->connection())
     68#define MESSAGE_CHECK(assertion) MESSAGE_CHECK_BASE(assertion, m_process->connection())
     69#define MESSAGE_CHECK_URL(url) MESSAGE_CHECK_BASE(m_process->checkURLReceivedFromWebProcess(url), m_process->connection())
    6970
    7071using namespace WebCore;
     
    440441    MESSAGE_CHECK(frame);
    441442    MESSAGE_CHECK(frame->page() == page);
    442    
     443    MESSAGE_CHECK_URL(sourceURLString);
     444    MESSAGE_CHECK_URL(destinationURLString);
     445
    443446    m_historyClient.didPerformClientRedirect(this, page, sourceURLString, destinationURLString, frame);
    444447}
     
    456459    MESSAGE_CHECK(frame);
    457460    MESSAGE_CHECK(frame->page() == page);
    458    
     461    MESSAGE_CHECK_URL(sourceURLString);
     462    MESSAGE_CHECK_URL(destinationURLString);
     463
    459464    m_historyClient.didPerformServerRedirect(this, page, sourceURLString, destinationURLString, frame);
    460465}
     
    469474    MESSAGE_CHECK(frame);
    470475    MESSAGE_CHECK(frame->page() == page);
     476    MESSAGE_CHECK_URL(url);
    471477
    472478    m_historyClient.didUpdateHistoryTitle(this, page, title, url, frame);
     
    554560void WebContext::getPluginPath(const String& mimeType, const String& urlString, String& pluginPath)
    555561{
     562    MESSAGE_CHECK_URL(urlString);
     563
    556564    String newMimeType = mimeType.lower();
    557565
    558     PluginModuleInfo plugin = pluginInfoStore().findPlugin(newMimeType, KURL(ParsedURLString, urlString));
     566    PluginModuleInfo plugin = pluginInfoStore().findPlugin(newMimeType, KURL(KURL(), urlString));
    559567    if (!plugin.path)
    560568        return;
  • trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp

    r95708 r95747  
    9191#define MERGE_WHEEL_EVENTS 1
    9292
    93 #define MESSAGE_CHECK(assertion) MESSAGE_CHECK_BASE(assertion, process()->connection())
     93#define MESSAGE_CHECK(assertion) MESSAGE_CHECK_BASE(assertion, m_process->connection())
     94#define MESSAGE_CHECK_URL(url) MESSAGE_CHECK_BASE(m_process->checkURLReceivedFromWebProcess(url), m_process->connection())
    9495
    9596using namespace WebCore;
     
    297298
    298299    SandboxExtension::Handle sandboxExtensionHandle;
    299     initializeSandboxExtensionHandle(KURL(KURL(), item->url()), sandboxExtensionHandle);
     300    bool createdExtension = maybeInitializeSandboxExtensionHandle(KURL(KURL(), item->url()), sandboxExtensionHandle);
     301    if (createdExtension)
     302        process()->willAcquireUniversalFileReadSandboxExtension();
    300303    process()->send(Messages::WebPage::GoToBackForwardItem(item->itemID(), sandboxExtensionHandle), m_pageID);
    301304    process()->responsivenessTimer()->start();
     
    397400}
    398401
    399 void WebPageProxy::initializeSandboxExtensionHandle(const KURL& url, SandboxExtension::Handle& sandboxExtensionHandle)
     402bool WebPageProxy::maybeInitializeSandboxExtensionHandle(const KURL& url, SandboxExtension::Handle& sandboxExtensionHandle)
    400403{
    401404    if (!url.isLocalFile())
    402         return;
     405        return false;
    403406
    404407    // Don't give the inspector full access to the file system.
    405408    if (WebInspectorProxy::isInspectorPage(this))
    406         return;
     409        return false;
    407410
    408411    SandboxExtension::createHandle("/", SandboxExtension::ReadOnly, sandboxExtensionHandle);
     412    return true;
    409413}
    410414
     
    417421
    418422    SandboxExtension::Handle sandboxExtensionHandle;
    419     initializeSandboxExtensionHandle(KURL(KURL(), url), sandboxExtensionHandle);
     423    bool createdExtension = maybeInitializeSandboxExtensionHandle(KURL(KURL(), url), sandboxExtensionHandle);
     424    if (createdExtension)
     425        process()->willAcquireUniversalFileReadSandboxExtension();
    420426    process()->send(Messages::WebPage::LoadURL(url, sandboxExtensionHandle), m_pageID);
    421427    process()->responsivenessTimer()->start();
     
    430436
    431437    SandboxExtension::Handle sandboxExtensionHandle;
    432     initializeSandboxExtensionHandle(urlRequest->resourceRequest().url(), sandboxExtensionHandle);
     438    bool createdExtension = maybeInitializeSandboxExtensionHandle(urlRequest->resourceRequest().url(), sandboxExtensionHandle);
     439    if (createdExtension)
     440        process()->willAcquireUniversalFileReadSandboxExtension();
    433441    process()->send(Messages::WebPage::LoadURLRequest(urlRequest->resourceRequest(), sandboxExtensionHandle), m_pageID);
    434442    process()->responsivenessTimer()->start();
     
    440448        reattachToWebProcess();
    441449
     450    process()->willLoadHTMLStringWithBaseURL(baseURL);
    442451    process()->send(Messages::WebPage::LoadHTMLString(htmlString, baseURL), m_pageID);
    443452    process()->responsivenessTimer()->start();
     
    452461        m_mainFrame->setUnreachableURL(unreachableURL);
    453462
     463    process()->willLoadHTMLStringWithBaseURL(baseURL);
    454464    process()->send(Messages::WebPage::LoadAlternateHTMLString(htmlString, baseURL, unreachableURL), m_pageID);
    455465    process()->responsivenessTimer()->start();
     
    503513
    504514    SandboxExtension::Handle sandboxExtensionHandle;
    505     initializeSandboxExtensionHandle(KURL(KURL(), forwardItem->url()), sandboxExtensionHandle);
     515    bool createdExtension = maybeInitializeSandboxExtensionHandle(KURL(KURL(), forwardItem->url()), sandboxExtensionHandle);
     516    if (createdExtension)
     517        process()->willAcquireUniversalFileReadSandboxExtension();
    506518    process()->send(Messages::WebPage::GoForward(forwardItem->itemID(), sandboxExtensionHandle), m_pageID);
    507519    process()->responsivenessTimer()->start();
     
    528540
    529541    SandboxExtension::Handle sandboxExtensionHandle;
    530     initializeSandboxExtensionHandle(KURL(KURL(), backItem->url()), sandboxExtensionHandle);
     542    bool createdExtension = maybeInitializeSandboxExtensionHandle(KURL(KURL(), backItem->url()), sandboxExtensionHandle);
     543    if (createdExtension)
     544        process()->willAcquireUniversalFileReadSandboxExtension();
    531545    process()->send(Messages::WebPage::GoBack(backItem->itemID(), sandboxExtensionHandle), m_pageID);
    532546    process()->responsivenessTimer()->start();
     
    548562
    549563    SandboxExtension::Handle sandboxExtensionHandle;
    550     initializeSandboxExtensionHandle(KURL(KURL(), item->url()), sandboxExtensionHandle);
     564    bool createdExtension = maybeInitializeSandboxExtensionHandle(KURL(KURL(), item->url()), sandboxExtensionHandle);
     565    if (createdExtension)
     566        process()->willAcquireUniversalFileReadSandboxExtension();
    551567    process()->send(Messages::WebPage::GoToBackForwardItem(item->itemID(), sandboxExtensionHandle), m_pageID);
    552568    process()->responsivenessTimer()->start();
     
    15251541    WebFrameProxy* frame = process()->webFrame(frameID);
    15261542    MESSAGE_CHECK(frame);
     1543    MESSAGE_CHECK_URL(url);
    15271544
    15281545    frame->setUnreachableURL(unreachableURL);
     
    15411558    WebFrameProxy* frame = process()->webFrame(frameID);
    15421559    MESSAGE_CHECK(frame);
     1560    MESSAGE_CHECK_URL(url);
    15431561
    15441562    frame->didReceiveServerRedirectForProvisionalLoad(url);
     
    16621680    WebFrameProxy* frame = process()->webFrame(frameID);
    16631681    MESSAGE_CHECK(frame);
     1682    MESSAGE_CHECK_URL(url);
    16641683
    16651684    clearPendingAPIRequestURL();
     
    17741793    WebFrameProxy* frame = process()->webFrame(frameID);
    17751794    MESSAGE_CHECK(frame);
     1795    MESSAGE_CHECK_URL(request.url());
    17761796
    17771797    NavigationType navigationType = static_cast<NavigationType>(opaqueNavigationType);
     
    18081828    WebFrameProxy* frame = process()->webFrame(frameID);
    18091829    MESSAGE_CHECK(frame);
     1830    MESSAGE_CHECK_URL(request.url());
    18101831
    18111832    NavigationType navigationType = static_cast<NavigationType>(opaqueNavigationType);
     
    18271848    WebFrameProxy* frame = process()->webFrame(frameID);
    18281849    MESSAGE_CHECK(frame);
    1829 
     1850    MESSAGE_CHECK_URL(request.url());
     1851    MESSAGE_CHECK_URL(response.url());
     1852   
    18301853    RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
    18311854
     
    18871910    WebFrameProxy* frame = process()->webFrame(frameID);
    18881911    MESSAGE_CHECK(frame);
     1912    MESSAGE_CHECK_URL(request.url());
    18891913
    18901914    m_resourceLoadClient.didInitiateLoadForResource(this, frame, resourceIdentifier, request, pageIsProvisionallyLoading);
     
    18951919    WebFrameProxy* frame = process()->webFrame(frameID);
    18961920    MESSAGE_CHECK(frame);
     1921    MESSAGE_CHECK_URL(request.url());
    18971922
    18981923    m_resourceLoadClient.didSendRequestForResource(this, frame, resourceIdentifier, request, redirectResponse);
     
    19031928    WebFrameProxy* frame = process()->webFrame(frameID);
    19041929    MESSAGE_CHECK(frame);
     1930    MESSAGE_CHECK_URL(response.url());
    19051931
    19061932    m_resourceLoadClient.didReceiveResponseForResource(this, frame, resourceIdentifier, response);
     
    20172043void WebPageProxy::missingPluginButtonClicked(const String& mimeType, const String& url, const String& pluginsPageURL)
    20182044{
     2045    MESSAGE_CHECK_URL(url);
     2046    MESSAGE_CHECK_URL(pluginsPageURL);
     2047
    20192048    m_uiClient.missingPluginButtonClicked(this, mimeType, url, pluginsPageURL);
    20202049}
  • trunk/Source/WebKit2/UIProcess/WebPageProxy.h

    r95708 r95747  
    775775    void setPendingAPIRequestURL(const String& pendingAPIRequestURL) { m_pendingAPIRequestURL = pendingAPIRequestURL; }
    776776
    777     void initializeSandboxExtensionHandle(const WebCore::KURL&, SandboxExtension::Handle&);
     777    bool maybeInitializeSandboxExtensionHandle(const WebCore::KURL&, SandboxExtension::Handle&);
    778778
    779779#if PLATFORM(MAC)
  • trunk/Source/WebKit2/UIProcess/WebProcessProxy.cpp

    r95708 r95747  
    4646using namespace std;
    4747
     48#define MESSAGE_CHECK_URL(url) MESSAGE_CHECK_BASE(checkURLReceivedFromWebProcess(url), connection())
     49
    4850namespace WebKit {
    4951
     
    6870    : m_responsivenessTimer(this)
    6971    , m_context(context)
     72    , m_mayHaveUniversalFileReadSandboxExtension(false)
    7073{
    7174    connect();
     
    201204}
    202205
     206void WebProcessProxy::willLoadHTMLStringWithBaseURL(const String& urlString)
     207{
     208    KURL url(KURL(), urlString);
     209    if (!url.isLocalFile())
     210        return;
     211
     212    // Client loads an alternate string. This doesn't grant universal file read, but the web process is assumed
     213    // to have read access to this directory already.
     214    m_localPathsWithAssumedReadAccess.add(url.fileSystemPath());
     215}
     216
     217bool WebProcessProxy::checkURLReceivedFromWebProcess(const String& urlString)
     218{
     219    return checkURLReceivedFromWebProcess(KURL(KURL(), urlString));
     220}
     221
     222bool WebProcessProxy::checkURLReceivedFromWebProcess(const KURL& url)
     223{
     224    // FIXME: Consider checking that the URL is valid. Currently, WebProcess sends invalid URLs in many cases, but it probably doesn't have good reasons to do that.
     225
     226    // Any other non-file URL is OK.
     227    if (!url.isLocalFile())
     228        return true;
     229
     230    // Any file URL is also OK if we've loaded a file URL through API before, granting universal read access.
     231    if (m_mayHaveUniversalFileReadSandboxExtension)
     232        return true;
     233
     234    // If we loaded a string with a file base URL before, loading resources from that subdirectory is fine.
     235    // There are no ".." components, because all URLs received from WebProcess are parsed with KURL, which removes those.
     236    String path = url.fileSystemPath();
     237    for (HashSet<String>::const_iterator iter = m_localPathsWithAssumedReadAccess.begin(); iter != m_localPathsWithAssumedReadAccess.end(); ++iter) {
     238        if (path.startsWith(*iter))
     239            return true;
     240    }
     241
     242    // A Web process that was never asked to load a file URL should not ever ask us to do anything with a file URL.
     243    return false;
     244}
     245
    203246void WebProcessProxy::addBackForwardItem(uint64_t itemID, const String& originalURL, const String& url, const String& title, const CoreIPC::DataReference& backForwardData)
    204247{
     248    MESSAGE_CHECK_URL(originalURL);
     249    MESSAGE_CHECK_URL(url);
     250
    205251    std::pair<WebBackForwardListItemMap::iterator, bool> result = m_backForwardListItemMap.add(itemID, 0);
    206252    if (result.second) {
  • trunk/Source/WebKit2/UIProcess/WebProcessProxy.h

    r95708 r95747  
    105105    void registerNewWebBackForwardListItem(WebBackForwardListItem*);
    106106
     107    void willAcquireUniversalFileReadSandboxExtension() { m_mayHaveUniversalFileReadSandboxExtension = true; }
     108    void willLoadHTMLStringWithBaseURL(const String&);
     109
     110    bool checkURLReceivedFromWebProcess(const String&);
     111    bool checkURLReceivedFromWebProcess(const WebCore::KURL&);
     112
    107113    // FIXME: This variant of send is deprecated. All clients should move to an overload that take a message type.
    108114    template<typename E, typename T> bool deprecatedSend(E messageID, uint64_t destinationID, const T& arguments);
     
    176182    RefPtr<WebContext> m_context;
    177183
     184    bool m_mayHaveUniversalFileReadSandboxExtension; // True if a read extension for "/" was ever granted - we don't track whether WebProcess still has it.
     185    HashSet<String> m_localPathsWithAssumedReadAccess;
     186
    178187    HashMap<uint64_t, WebPageProxy*> m_pageMap;
    179188    WebFrameProxyMap m_frameMap;
  • trunk/Source/WebKit2/UIProcess/cf/WebPageProxyCF.cpp

    r95708 r95747  
    167167                    SandboxExtension::Handle sandboxExtensionHandle;
    168168                    if (WebBackForwardListItem* item = m_backForwardList->currentItem()) {
    169                         initializeSandboxExtensionHandle(KURL(KURL(), item->url()), sandboxExtensionHandle);
     169                        bool createdExtension = maybeInitializeSandboxExtensionHandle(KURL(KURL(), item->url()), sandboxExtensionHandle);
     170                        if (createdExtension)
     171                            process()->willAcquireUniversalFileReadSandboxExtension();
    170172                        setPendingAPIRequestURL(item->url());
    171173                    }
Note: See TracChangeset for help on using the changeset viewer.