diff options
author | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2015-04-17 17:16:23 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2015-04-28 19:29:19 +0000 |
commit | 9cbcd93cfe0ba6f7531574f7784e8978bd723110 (patch) | |
tree | 2f7c926e7f334669b7885ecd219a197bd181de0c | |
parent | 8ce4aba7d1742f07c01f2786e75ff7a5c8386aa6 (diff) | |
download | qtwebkit-9cbcd93cfe0ba6f7531574f7784e8978bd723110.tar.gz |
Enforce no remote access from local URLs for XHR
Add a specific setting to disable remote access for local URLs and also
enforce that on data-URLs loaded owned by local URLs.
Change-Id: Ied8ec141eb1c28775644fce184a4759a79e1d177
Task-number: QTBUG-45556
Reviewed-by: Dmitry Shachnev <mitya57@gmail.com>
Reviewed-by: Michael BrĂ¼ning <michael.bruning@theqtcompany.com>
-rw-r--r-- | Source/WebCore/dom/Document.cpp | 23 | ||||
-rw-r--r-- | Source/WebCore/loader/CrossOriginAccessControl.cpp | 5 | ||||
-rw-r--r-- | Source/WebCore/loader/DocumentThreadableLoader.cpp | 5 | ||||
-rw-r--r-- | Source/WebCore/page/EventSource.cpp | 2 | ||||
-rw-r--r-- | Source/WebCore/page/SecurityOrigin.cpp | 8 | ||||
-rw-r--r-- | Source/WebCore/page/SecurityOrigin.h | 7 | ||||
-rw-r--r-- | Source/WebCore/page/Settings.in | 1 | ||||
-rw-r--r-- | Source/WebCore/xml/XMLHttpRequest.cpp | 2 | ||||
-rw-r--r-- | Source/WebKit/qt/Api/qwebsettings.cpp | 5 |
9 files changed, 48 insertions, 10 deletions
diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp index 0e778e642..af63b141f 100644 --- a/Source/WebCore/dom/Document.cpp +++ b/Source/WebCore/dom/Document.cpp @@ -4572,12 +4572,22 @@ void Document::initSecurityContext() if (settings->allowUniversalAccessFromFileURLs() || m_frame->loader()->client()->shouldForceUniversalAccessFromLocalURL(m_url)) { // Some clients want local URLs to have universal access, but that setting is dangerous for other clients. securityOrigin()->grantUniversalAccess(); - } else if (!settings->allowFileAccessFromFileURLs()) { - // Some clients want local URLs to have even tighter restrictions by default, and not be able to access other local files. - // FIXME 81578: The naming of this is confusing. Files with restricted access to other local files - // still can have other privileges that can be remembered, thereby not making them unique origins. - securityOrigin()->enforceFilePathSeparation(); + } else { + if (!settings->allowRemoteAccessFromFileURLs()) + securityOrigin()->denyCrossOriginRequests(); + if (!settings->allowFileAccessFromFileURLs()) { + // Some clients want local URLs to have even tighter restrictions by default, and not be able to access other local files. + // FIXME 81578: The naming of this is confusing. Files with restricted access to other local files + // still can have other privileges that can be remembered, thereby not making them unique origins. + securityOrigin()->enforceFilePathSeparation(); + } } + } else if (securityOrigin()->isUnique()) { + Frame* ownerFrame = m_frame->tree()->parent(); + if (!ownerFrame) + ownerFrame = m_frame->loader()->opener(); + if (ownerFrame && !ownerFrame->document()->securityOrigin()->allowsCrossOriginRequests()) + securityOrigin()->denyCrossOriginRequests(); } securityOrigin()->setStorageBlockingPolicy(settings->storageBlockingPolicy()); } @@ -4612,7 +4622,8 @@ void Document::initSecurityContext() // but we're also sandboxed, the only thing we inherit is the ability // to load local resources. This lets about:blank iframes in file:// // URL documents load images and other resources from the file system. - if (ownerFrame->document()->securityOrigin()->canLoadLocalResources()) + if (ownerFrame->document()->securityOrigin()->canLoadLocalResources() && + !ownerFrame->document()->securityOrigin()->enforcesFilePathSeparation()) securityOrigin()->grantLoadLocalResources(); return; } diff --git a/Source/WebCore/loader/CrossOriginAccessControl.cpp b/Source/WebCore/loader/CrossOriginAccessControl.cpp index 7b50dab0c..7d011906e 100644 --- a/Source/WebCore/loader/CrossOriginAccessControl.cpp +++ b/Source/WebCore/loader/CrossOriginAccessControl.cpp @@ -138,6 +138,11 @@ bool passesAccessControlCheck(const ResourceResponse& response, StoredCredential AtomicallyInitializedStatic(AtomicString&, accessControlAllowOrigin = *new AtomicString("access-control-allow-origin", AtomicString::ConstructFromLiteral)); AtomicallyInitializedStatic(AtomicString&, accessControlAllowCredentials = *new AtomicString("access-control-allow-credentials", AtomicString::ConstructFromLiteral)); + if (!securityOrigin->allowsCrossOriginRequests()) { + errorDescription = "Cannot make any cross origin requests from " + securityOrigin->toString() + "."; + return false; + } + // A wildcard Access-Control-Allow-Origin can not be used if credentials are to be sent, // even with Access-Control-Allow-Credentials set to true. const String& accessControlOriginString = response.httpHeaderField(accessControlAllowOrigin); diff --git a/Source/WebCore/loader/DocumentThreadableLoader.cpp b/Source/WebCore/loader/DocumentThreadableLoader.cpp index e8fe0185e..d51751ca5 100644 --- a/Source/WebCore/loader/DocumentThreadableLoader.cpp +++ b/Source/WebCore/loader/DocumentThreadableLoader.cpp @@ -127,6 +127,11 @@ void DocumentThreadableLoader::makeSimpleCrossOriginAccessRequest(const Resource return; } + if (!securityOrigin()->allowsCrossOriginRequests()) { + m_client->didFailAccessControlCheck(ResourceError(errorDomainWebKitInternal, 0, request.url().string(), "Cross origin requests are not allowed from " + securityOrigin()->toString() + ".")); + return; + } + loadRequest(request, DoSecurityCheck); } diff --git a/Source/WebCore/page/EventSource.cpp b/Source/WebCore/page/EventSource.cpp index 77a8e6f33..d3e6bbc6b 100644 --- a/Source/WebCore/page/EventSource.cpp +++ b/Source/WebCore/page/EventSource.cpp @@ -132,7 +132,7 @@ void EventSource::connect() options.sniffContent = DoNotSniffContent; options.allowCredentials = (origin->canRequest(m_url) || m_withCredentials) ? AllowStoredCredentials : DoNotAllowStoredCredentials; options.preflightPolicy = PreventPreflight; - options.crossOriginRequestPolicy = UseAccessControl; + options.crossOriginRequestPolicy = origin->allowsCrossOriginRequests() ? UseAccessControl : DenyCrossOriginRequests; options.dataBufferingPolicy = DoNotBufferData; options.securityOrigin = origin; diff --git a/Source/WebCore/page/SecurityOrigin.cpp b/Source/WebCore/page/SecurityOrigin.cpp index cebc89684..ae2822aaa 100644 --- a/Source/WebCore/page/SecurityOrigin.cpp +++ b/Source/WebCore/page/SecurityOrigin.cpp @@ -127,6 +127,7 @@ SecurityOrigin::SecurityOrigin(const KURL& url) , m_storageBlockingPolicy(AllowAllStorage) , m_enforceFilePathSeparation(false) , m_needsDatabaseIdentifierQuirkForFiles(false) + , m_deniedCORS(false) { // document.domain starts as m_host, but can be set by the DOM. m_domain = m_host; @@ -153,6 +154,7 @@ SecurityOrigin::SecurityOrigin() , m_storageBlockingPolicy(AllowAllStorage) , m_enforceFilePathSeparation(false) , m_needsDatabaseIdentifierQuirkForFiles(false) + , m_deniedCORS(false) { } @@ -169,6 +171,7 @@ SecurityOrigin::SecurityOrigin(const SecurityOrigin* other) , m_storageBlockingPolicy(other->m_storageBlockingPolicy) , m_enforceFilePathSeparation(other->m_enforceFilePathSeparation) , m_needsDatabaseIdentifierQuirkForFiles(other->m_needsDatabaseIdentifierQuirkForFiles) + , m_deniedCORS(other->m_deniedCORS) { } @@ -442,6 +445,11 @@ void SecurityOrigin::grantUniversalAccess() m_universalAccess = true; } +void SecurityOrigin::denyCrossOriginRequests() +{ + m_deniedCORS = true; +} + #if ENABLE(CACHE_PARTITIONING) String SecurityOrigin::cachePartition() const { diff --git a/Source/WebCore/page/SecurityOrigin.h b/Source/WebCore/page/SecurityOrigin.h index 8572f4ce4..980fcfffb 100644 --- a/Source/WebCore/page/SecurityOrigin.h +++ b/Source/WebCore/page/SecurityOrigin.h @@ -139,6 +139,11 @@ public: // WARNING: This is an extremely powerful ability. Use with caution! void grantUniversalAccess(); + // Explicitly deny the ability to issue cross origin requests. + // + void denyCrossOriginRequests(); + bool allowsCrossOriginRequests() const { return !m_deniedCORS; } + void setStorageBlockingPolicy(StorageBlockingPolicy policy) { m_storageBlockingPolicy = policy; } #if ENABLE(CACHE_PARTITIONING) @@ -173,6 +178,7 @@ public: // FIXME 81578: The naming of this is confusing. Files with restricted access to other local files // still can have other privileges that can be remembered, thereby not making them unique. void enforceFilePathSeparation(); + bool enforcesFilePathSeparation() const { return m_enforceFilePathSeparation; } // Convert this SecurityOrigin into a string. The string // representation of a SecurityOrigin is similar to a URL, except it @@ -231,6 +237,7 @@ private: StorageBlockingPolicy m_storageBlockingPolicy; bool m_enforceFilePathSeparation; bool m_needsDatabaseIdentifierQuirkForFiles; + bool m_deniedCORS; }; } // namespace WebCore diff --git a/Source/WebCore/page/Settings.in b/Source/WebCore/page/Settings.in index dd51d6850..c66ab0be6 100644 --- a/Source/WebCore/page/Settings.in +++ b/Source/WebCore/page/Settings.in @@ -49,6 +49,7 @@ caretBrowsingEnabled initial=false localStorageEnabled initial=false allowUniversalAccessFromFileURLs initial=true allowFileAccessFromFileURLs initial=true +allowRemoteAccessFromFileURLs initial=true javaScriptCanOpenWindowsAutomatically initial=false supportsMultipleWindows initial=true javaScriptCanAccessClipboard initial=false diff --git a/Source/WebCore/xml/XMLHttpRequest.cpp b/Source/WebCore/xml/XMLHttpRequest.cpp index 09e7fe582..853ec4756 100644 --- a/Source/WebCore/xml/XMLHttpRequest.cpp +++ b/Source/WebCore/xml/XMLHttpRequest.cpp @@ -784,7 +784,7 @@ void XMLHttpRequest::createRequest(ExceptionCode& ec) options.sniffContent = DoNotSniffContent; options.preflightPolicy = uploadEvents ? ForcePreflight : ConsiderPreflight; options.allowCredentials = (m_sameOriginRequest || m_includeCredentials) ? AllowStoredCredentials : DoNotAllowStoredCredentials; - options.crossOriginRequestPolicy = UseAccessControl; + options.crossOriginRequestPolicy = securityOrigin()->allowsCrossOriginRequests() ? UseAccessControl : DenyCrossOriginRequests; options.securityOrigin = securityOrigin(); #if ENABLE(RESOURCE_TIMING) options.initiator = cachedResourceRequestInitiators().xmlhttprequest; diff --git a/Source/WebKit/qt/Api/qwebsettings.cpp b/Source/WebKit/qt/Api/qwebsettings.cpp index cb969a3df..f55b6d721 100644 --- a/Source/WebKit/qt/Api/qwebsettings.cpp +++ b/Source/WebKit/qt/Api/qwebsettings.cpp @@ -272,9 +272,10 @@ void QWebSettingsPrivate::apply() global->attributes.value(QWebSettings::LocalStorageEnabled)); settings->setLocalStorageEnabled(value); - value = attributes.value(QWebSettings::LocalContentCanAccessRemoteUrls, + bool remoteAccess = attributes.value(QWebSettings::LocalContentCanAccessRemoteUrls, global->attributes.value(QWebSettings::LocalContentCanAccessRemoteUrls)); - settings->setAllowUniversalAccessFromFileURLs(value); + settings->setAllowUniversalAccessFromFileURLs(remoteAccess); + settings->setAllowRemoteAccessFromFileURLs(remoteAccess); value = attributes.value(QWebSettings::LocalContentCanAccessFileUrls, global->attributes.value(QWebSettings::LocalContentCanAccessFileUrls)); |