Bug 1147821 - Update IndexedDB to use common StorageAllowedForWindow logic, r=khuey

This commit is contained in:
Michael Layzell 2015-07-15 17:01:02 -04:00
Родитель c98f12f1ae
Коммит cd6e65d4d5
7 изменённых файлов: 72 добавлений и 51 удалений

Просмотреть файл

@ -362,8 +362,13 @@ IDBFactory::AllowedForWindowInternal(nsPIDOMWindow* aWindow,
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;
}
@ -373,26 +378,21 @@ IDBFactory::AllowedForWindowInternal(nsPIDOMWindow* aWindow,
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) {
@ -400,29 +400,13 @@ IDBFactory::AllowedForWindowInternal(nsPIDOMWindow* aWindow,
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;
}
}

Просмотреть файл

@ -10,11 +10,31 @@
<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 =
@ -41,8 +61,12 @@
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) {

Просмотреть файл

@ -46,6 +46,7 @@
#include "mozilla/ipc/PBackgroundChild.h"
#include "mozilla/ipc/PBackgroundSharedTypes.h"
#include "mozilla/unused.h"
#include "mozilla/EnumSet.h"
#include "nsContentUtils.h"
#include "nsGlobalWindow.h"
@ -4057,6 +4058,9 @@ ServiceWorkerManager::CreateServiceWorker(nsIPrincipal* aPrincipal,
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);
@ -4076,9 +4080,12 @@ ServiceWorkerManager::CreateServiceWorker(nsIPrincipal* aPrincipal,
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));

Просмотреть файл

@ -1673,7 +1673,7 @@ WorkerLoadInfo::WorkerLoadInfo()
, mPrincipalIsSystem(false)
, mIsInPrivilegedApp(false)
, mIsInCertifiedApp(false)
, mIndexedDBAllowed(false)
, mStorageAllowed(false)
, mPrivateBrowsing(true)
, mServiceWorkersTestingInWindow(false)
{
@ -1732,7 +1732,7 @@ WorkerLoadInfo::StealFrom(WorkerLoadInfo& aOther)
mPrincipalIsSystem = aOther.mPrincipalIsSystem;
mIsInPrivilegedApp = aOther.mIsInPrivilegedApp;
mIsInCertifiedApp = aOther.mIsInCertifiedApp;
mIndexedDBAllowed = aOther.mIndexedDBAllowed;
mStorageAllowed = aOther.mStorageAllowed;
mPrivateBrowsing = aOther.mPrivateBrowsing;
mServiceWorkersTestingInWindow = aOther.mServiceWorkersTestingInWindow;
}
@ -4266,13 +4266,16 @@ WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindow* aWindow,
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);
@ -4391,7 +4394,9 @@ WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindow* aWindow,
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
@ -4433,7 +4438,7 @@ WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindow* aWindow,
loadInfo.mXHRParamsAllowed = true;
loadInfo.mFromWindow = false;
loadInfo.mWindowID = UINT64_MAX;
loadInfo.mIndexedDBAllowed = true;
loadInfo.mStorageAllowed = true;
loadInfo.mPrivateBrowsing = false;
}

Просмотреть файл

@ -766,9 +766,9 @@ public:
}
bool
IsIndexedDBAllowed() const
IsStorageAllowed() const
{
return mLoadInfo.mIndexedDBAllowed;
return mLoadInfo.mStorageAllowed;
}
bool

Просмотреть файл

@ -358,8 +358,9 @@ WorkerGlobalScope::GetIndexedDB(ErrorResult& aErrorResult)
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;
}

Просмотреть файл

@ -273,7 +273,7 @@ struct WorkerLoadInfo
bool mPrincipalIsSystem;
bool mIsInPrivilegedApp;
bool mIsInCertifiedApp;
bool mIndexedDBAllowed;
bool mStorageAllowed;
bool mPrivateBrowsing;
bool mServiceWorkersTestingInWindow;