summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2015-04-17 17:16:23 +0200
committerAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2015-04-28 19:29:19 +0000
commit9cbcd93cfe0ba6f7531574f7784e8978bd723110 (patch)
tree2f7c926e7f334669b7885ecd219a197bd181de0c
parent8ce4aba7d1742f07c01f2786e75ff7a5c8386aa6 (diff)
downloadqtwebkit-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.cpp23
-rw-r--r--Source/WebCore/loader/CrossOriginAccessControl.cpp5
-rw-r--r--Source/WebCore/loader/DocumentThreadableLoader.cpp5
-rw-r--r--Source/WebCore/page/EventSource.cpp2
-rw-r--r--Source/WebCore/page/SecurityOrigin.cpp8
-rw-r--r--Source/WebCore/page/SecurityOrigin.h7
-rw-r--r--Source/WebCore/page/Settings.in1
-rw-r--r--Source/WebCore/xml/XMLHttpRequest.cpp2
-rw-r--r--Source/WebKit/qt/Api/qwebsettings.cpp5
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));