| author | Michael Layzell <michael@thelayzells.com> |
| Wed, 15 Jul 2015 17:01:02 -0400 | |
| changeset 259806 | cc93773031259aecc93d38e2e69efab68d39a644 |
| parent 259805 | d67c4fd50c16f587c7e2b27a953ff8ffbf26234f |
| child 259807 | dfeb2c9934355465442383a740e6b9bd05fc12eb |
| push id | 29292 |
| push user | ryanvm@gmail.com |
| push date | Fri, 28 Aug 2015 19:28:32 +0000 |
| treeherder | mozilla-central@28c11736db63 [default view] [failures only] |
| reviewers | khuey |
| bugs | 1147821 |
| milestone | 43.0a1 |
| first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
| last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/indexedDB/IDBFactory.cpp +++ b/dom/indexedDB/IDBFactory.cpp @@ -357,77 +357,61 @@ IDBFactory::AllowedForWindowInternal(nsP MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(aWindow); MOZ_ASSERT(aWindow->IsInnerWindow()); if (NS_WARN_IF(!IndexedDatabaseManager::GetOrCreate())) { return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; } - nsIDocument* document = aWindow->GetExtantDoc(); - if (document->GetSandboxFlags() & SANDBOXED_ORIGIN) { + nsContentUtils::StorageAccess access = + nsContentUtils::StorageAllowedForWindow(aWindow); + + // the factory callsite records whether the browser is in private browsing. + // and thus we don't have to respect that setting here. IndexedDB has no + // concept of session-local storage, and thus ignores it. + if (access == nsContentUtils::StorageAccess::eDeny) { return NS_ERROR_DOM_SECURITY_ERR; } nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(aWindow); MOZ_ASSERT(sop); nsCOMPtr<nsIPrincipal> principal = sop->GetPrincipal(); if (NS_WARN_IF(!principal)) { return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; + } - bool isSystemPrincipal; - if (!AllowedForPrincipal(principal, &isSystemPrincipal)) { - return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; - } - - if (isSystemPrincipal) { + if (nsContentUtils::IsSystemPrincipal(principal)) { principal.forget(aPrincipal); return NS_OK; } - // Whitelist about:home, since it doesn't have a base domain it would not - // pass the ThirdPartyUtil check, though it should be able to use indexedDB. - bool skipThirdPartyCheck = false; - + // About URIs shouldn't be able to access IndexedDB unless they have the + // nsIAboutModule::ENABLE_INDEXED_DB flag set on them. nsCOMPtr<nsIURI> uri; MOZ_ALWAYS_TRUE(NS_SUCCEEDED(principal->GetURI(getter_AddRefs(uri)))); + MOZ_ASSERT(uri); - bool isAbout; + bool isAbout = false; MOZ_ALWAYS_TRUE(NS_SUCCEEDED(uri->SchemeIs("about", &isAbout))); if (isAbout) { nsCOMPtr<nsIAboutModule> module; if (NS_SUCCEEDED(NS_GetAboutModule(uri, getter_AddRefs(module)))) { uint32_t flags; if (NS_SUCCEEDED(module->GetURIFlags(uri, &flags))) { - skipThirdPartyCheck = flags & nsIAboutModule::ENABLE_INDEXED_DB; + if (!(flags & nsIAboutModule::ENABLE_INDEXED_DB)) { + return NS_ERROR_DOM_NOT_SUPPORTED_ERR; + } } else { - NS_WARNING("GetURIFlags failed!"); + return NS_ERROR_DOM_NOT_SUPPORTED_ERR; } } else { - NS_WARNING("NS_GetAboutModule failed!"); - } - } - - if (!skipThirdPartyCheck) { - nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil = - do_GetService(THIRDPARTYUTIL_CONTRACTID); - MOZ_ASSERT(thirdPartyUtil); - - bool isThirdParty; - if (NS_WARN_IF(NS_FAILED( - thirdPartyUtil->IsThirdPartyWindow(aWindow, - nullptr, - &isThirdParty)))) { - return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; - } - - if (isThirdParty) { return NS_ERROR_DOM_NOT_SUPPORTED_ERR; } } principal.forget(aPrincipal); return NS_OK; }
--- a/dom/indexedDB/test/test_third_party.html +++ b/dom/indexedDB/test/test_third_party.html @@ -5,21 +5,41 @@ <html> <head> <title>Indexed Database Test</title> <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> <script type="text/javascript;version=1.7"> + const BEHAVIOR_ACCEPT = 0; + const BEHAVIOR_REJECTFOREIGN = 1; + const BEHAVIOR_REJECT = 2; + const BEHAVIOR_LIMITFOREIGN = 3; + const testData = [ - { host: "http://" + window.location.host, expectedResult: true }, - { host: "http://example.com", expectedResult: false }, - { host: "http://sub1.test2.example.org:8000", expectedResult: false }, - { host: "http://" + window.location.host, expectedResult: true } + { host: "http://" + window.location.host, cookieBehavior: BEHAVIOR_ACCEPT, expectedResult: true }, + { host: "http://example.com", cookieBehavior: BEHAVIOR_ACCEPT, expectedResult: true }, + { host: "http://sub1.test2.example.org:8000", cookieBehavior: BEHAVIOR_ACCEPT, expectedResult: true }, + { host: "http://" + window.location.host, cookieBehavior: BEHAVIOR_ACCEPT, expectedResult: true }, + + { host: "http://" + window.location.host, cookieBehavior: BEHAVIOR_REJECT, expectedResult: false }, + { host: "http://example.com", cookieBehavior: BEHAVIOR_REJECT, expectedResult: false }, + { host: "http://sub1.test2.example.org:8000", cookieBehavior: BEHAVIOR_REJECT, expectedResult: false }, + { host: "http://" + window.location.host, cookieBehavior: BEHAVIOR_REJECT, expectedResult: false }, + + { host: "http://" + window.location.host, cookieBehavior: BEHAVIOR_REJECTFOREIGN, expectedResult: true }, + { host: "http://example.com", cookieBehavior: BEHAVIOR_REJECTFOREIGN, expectedResult: false }, + { host: "http://sub1.test2.example.org:8000", cookieBehavior: BEHAVIOR_REJECTFOREIGN, expectedResult: false }, + { host: "http://" + window.location.host, cookieBehavior: BEHAVIOR_REJECTFOREIGN, expectedResult: true }, + + { host: "http://" + window.location.host, cookieBehavior: BEHAVIOR_LIMITFOREIGN, expectedResult: true }, + { host: "http://example.com", cookieBehavior: BEHAVIOR_LIMITFOREIGN, expectedResult: false }, + { host: "http://sub1.test2.example.org:8000", cookieBehavior: BEHAVIOR_LIMITFOREIGN, expectedResult: false }, + { host: "http://" + window.location.host, cookieBehavior: BEHAVIOR_LIMITFOREIGN, expectedResult: true } ]; const iframe1Path = window.location.pathname.replace("test_third_party.html", "third_party_iframe1.html"); const iframe2URL = "http://" + window.location.host + window.location.pathname.replace("test_third_party.html", @@ -36,18 +56,22 @@ function setiframe() { let iframe = document.getElementById("iframe1"); if (!testRunning) { testRunning = true; iframe.addEventListener("load", iframeLoaded, false); } - - iframe.src = testData[testIndex].host + iframe1Path; + SpecialPowers.pushPrefEnv({ + 'set': [["network.cookie.cookieBehavior", testData[testIndex].cookieBehavior]] + }, () => { + iframe.src = testData[testIndex].host + iframe1Path; + }); + // SpecialPowers.setIntPref("network.cookie.cookieBehavior", testData[testIndex].cookieBehavior); } function messageListener(event) { let message = eval(event.data); is(message.source, "iframe", "Good source"); is(message.result, testData[testIndex].expectedResult, "Good result");
--- a/dom/workers/ServiceWorkerManager.cpp +++ b/dom/workers/ServiceWorkerManager.cpp @@ -41,16 +41,17 @@ #include "mozilla/dom/NotificationEvent.h" #include "mozilla/dom/PromiseNativeHandler.h" #include "mozilla/dom/Request.h" #include "mozilla/dom/RootedDictionary.h" #include "mozilla/ipc/BackgroundChild.h" #include "mozilla/ipc/PBackgroundChild.h" #include "mozilla/ipc/PBackgroundSharedTypes.h" #include "mozilla/unused.h" +#include "mozilla/EnumSet.h" #include "nsContentUtils.h" #include "nsGlobalWindow.h" #include "nsNetUtil.h" #include "nsIURL.h" #include "nsProxyRelease.h" #include "nsQueryObject.h" #include "nsTArray.h" @@ -4052,16 +4053,19 @@ NS_IMETHODIMP ServiceWorkerManager::CreateServiceWorker(nsIPrincipal* aPrincipal, ServiceWorkerInfo* aInfo, nsIRunnable* aLoadFailedRunnable, ServiceWorker** aServiceWorker) { AssertIsOnMainThread(); MOZ_ASSERT(aPrincipal); + // Ensure that the IndexedDatabaseManager is initialized + NS_WARN_IF(!indexedDB::IndexedDatabaseManager::GetOrCreate()); + WorkerLoadInfo info; nsresult rv = NS_NewURI(getter_AddRefs(info.mBaseURI), aInfo->ScriptSpec(), nullptr, nullptr); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } info.mResolvedScriptURI = info.mBaseURI; @@ -4071,19 +4075,22 @@ ServiceWorkerManager::CreateServiceWorke rv = info.mBaseURI->GetHost(info.mDomain); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } info.mPrincipal = aPrincipal; - info.mIndexedDBAllowed = - indexedDB::IDBFactory::AllowedForPrincipal(aPrincipal); - info.mPrivateBrowsing = false; + nsContentUtils::StorageAccess access = + nsContentUtils::StorageAllowedForPrincipal(aPrincipal); + info.mStorageAllowed = + access > nsContentUtils::StorageAccess::ePrivateBrowsing; + + info.mPrivateBrowsing = false; nsCOMPtr<nsIContentSecurityPolicy> csp; rv = aPrincipal->GetCsp(getter_AddRefs(csp)); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } info.mCSP = csp;
--- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -1668,17 +1668,17 @@ WorkerLoadInfo::WorkerLoadInfo() , mServiceWorkerID(0) , mFromWindow(false) , mEvalAllowed(false) , mReportCSPViolations(false) , mXHRParamsAllowed(false) , mPrincipalIsSystem(false) , mIsInPrivilegedApp(false) , mIsInCertifiedApp(false) - , mIndexedDBAllowed(false) + , mStorageAllowed(false) , mPrivateBrowsing(true) , mServiceWorkersTestingInWindow(false) { MOZ_COUNT_CTOR(WorkerLoadInfo); } WorkerLoadInfo::~WorkerLoadInfo() { @@ -1727,17 +1727,17 @@ WorkerLoadInfo::StealFrom(WorkerLoadInfo mServiceWorkerID = aOther.mServiceWorkerID; mFromWindow = aOther.mFromWindow; mEvalAllowed = aOther.mEvalAllowed; mReportCSPViolations = aOther.mReportCSPViolations; mXHRParamsAllowed = aOther.mXHRParamsAllowed; mPrincipalIsSystem = aOther.mPrincipalIsSystem; mIsInPrivilegedApp = aOther.mIsInPrivilegedApp; mIsInCertifiedApp = aOther.mIsInCertifiedApp; - mIndexedDBAllowed = aOther.mIndexedDBAllowed; + mStorageAllowed = aOther.mStorageAllowed; mPrivateBrowsing = aOther.mPrivateBrowsing; mServiceWorkersTestingInWindow = aOther.mServiceWorkersTestingInWindow; } template <class Derived> class WorkerPrivateParent<Derived>::EventTarget final : public nsIEventTarget { @@ -4261,23 +4261,26 @@ WorkerPrivate::GetLoadInfo(JSContext* aC NS_WARNING("Failed to proxy release of channel, leaking instead!"); } return NS_ERROR_FAILURE; } loadInfo.mDomain = aParent->Domain(); loadInfo.mFromWindow = aParent->IsFromWindow(); loadInfo.mWindowID = aParent->WindowID(); - loadInfo.mIndexedDBAllowed = aParent->IsIndexedDBAllowed(); + loadInfo.mStorageAllowed = aParent->IsStorageAllowed(); loadInfo.mPrivateBrowsing = aParent->IsInPrivateBrowsing(); loadInfo.mServiceWorkersTestingInWindow = aParent->ServiceWorkersTestingInWindow(); } else { AssertIsOnMainThread(); + // Make sure that the IndexedDatabaseManager is set up + NS_WARN_IF(!indexedDB::IndexedDatabaseManager::GetOrCreate()); + nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager(); MOZ_ASSERT(ssm); bool isChrome = nsContentUtils::IsCallerChrome(); // First check to make sure the caller has permission to make a privileged // worker if they called the ChromeWorker/ChromeSharedWorker constructor. if (aIsChromeWorker && !isChrome) { @@ -4386,17 +4389,19 @@ WorkerPrivate::GetLoadInfo(JSContext* aC uint16_t appStatus = loadInfo.mPrincipal->GetAppStatus(); loadInfo.mIsInPrivilegedApp = (appStatus == nsIPrincipal::APP_STATUS_CERTIFIED || appStatus == nsIPrincipal::APP_STATUS_PRIVILEGED); loadInfo.mIsInCertifiedApp = (appStatus == nsIPrincipal::APP_STATUS_CERTIFIED); loadInfo.mFromWindow = true; loadInfo.mWindowID = globalWindow->WindowID(); - loadInfo.mIndexedDBAllowed = IDBFactory::AllowedForWindow(globalWindow); + nsContentUtils::StorageAccess access = + nsContentUtils::StorageAllowedForWindow(globalWindow); + loadInfo.mStorageAllowed = access > nsContentUtils::StorageAccess::eDeny; loadInfo.mPrivateBrowsing = nsContentUtils::IsInPrivateBrowsing(document); } else { // Not a window MOZ_ASSERT(isChrome); // We're being created outside of a window. Need to figure out the script // that is creating us in order for us to use relative URIs later on. JS::AutoFilename fileName; @@ -4428,17 +4433,17 @@ WorkerPrivate::GetLoadInfo(JSContext* aC } if (NS_FAILED(rv)) { return rv; } } loadInfo.mXHRParamsAllowed = true; loadInfo.mFromWindow = false; loadInfo.mWindowID = UINT64_MAX; - loadInfo.mIndexedDBAllowed = true; + loadInfo.mStorageAllowed = true; loadInfo.mPrivateBrowsing = false; } MOZ_ASSERT(loadInfo.mPrincipal); MOZ_ASSERT(isChrome || !loadInfo.mDomain.IsEmpty()); if (!nsContentUtils::GetContentSecurityPolicy(getter_AddRefs(loadInfo.mCSP))) { NS_WARNING("Failed to get CSP!");
--- a/dom/workers/WorkerPrivate.h +++ b/dom/workers/WorkerPrivate.h @@ -761,19 +761,19 @@ public: uint64_t NextMessagePortSerial() { AssertIsOnMainThread(); return mMessagePortSerial++; } bool - IsIndexedDBAllowed() const + IsStorageAllowed() const { - return mLoadInfo.mIndexedDBAllowed; + return mLoadInfo.mStorageAllowed; } bool IsInPrivateBrowsing() const { return mLoadInfo.mPrivateBrowsing; }
--- a/dom/workers/WorkerScope.cpp +++ b/dom/workers/WorkerScope.cpp @@ -353,18 +353,19 @@ WorkerGlobalScope::Fetch(const RequestOr already_AddRefed<IDBFactory> WorkerGlobalScope::GetIndexedDB(ErrorResult& aErrorResult) { mWorkerPrivate->AssertIsOnWorkerThread(); nsRefPtr<IDBFactory> indexedDB = mIndexedDB; if (!indexedDB) { - if (!mWorkerPrivate->IsIndexedDBAllowed()) { + if (!mWorkerPrivate->IsStorageAllowed()) { NS_WARNING("IndexedDB is not allowed in this worker!"); + aErrorResult = NS_ERROR_DOM_SECURITY_ERR; return nullptr; } JSContext* cx = mWorkerPrivate->GetJSContext(); MOZ_ASSERT(cx); JS::Rooted<JSObject*> owningObject(cx, GetGlobalJSObject()); MOZ_ASSERT(owningObject);
--- a/dom/workers/Workers.h +++ b/dom/workers/Workers.h @@ -268,17 +268,17 @@ struct WorkerLoadInfo bool mFromWindow; bool mEvalAllowed; bool mReportCSPViolations; bool mXHRParamsAllowed; bool mPrincipalIsSystem; bool mIsInPrivilegedApp; bool mIsInCertifiedApp; - bool mIndexedDBAllowed; + bool mStorageAllowed; bool mPrivateBrowsing; bool mServiceWorkersTestingInWindow; WorkerLoadInfo(); ~WorkerLoadInfo(); void StealFrom(WorkerLoadInfo& aOther); };