From 57535d8c79aaa800bb30a7cbb26a868d626a995a Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Fri, 12 Apr 2019 05:31:40 +0000 Subject: [PATCH] Bug 1536411 - StoragePrincipal - part 0 - WorkerPrivate::StorageAccess, r=Ehsan Differential Revision: https://phabricator.services.mozilla.com/D24024 --HG-- extra : moz-landing-system : lando --- dom/broadcastchannel/BroadcastChannel.cpp | 26 +++++++++---------- dom/cache/CacheStorage.cpp | 16 +++++++----- dom/clients/manager/ClientSource.cpp | 17 +++++------- dom/serviceworkers/ServiceWorkerPrivate.cpp | 4 +-- dom/workers/WorkerLoadInfo.cpp | 2 +- dom/workers/WorkerLoadInfo.h | 2 +- dom/workers/WorkerPrivate.cpp | 7 +++-- dom/workers/WorkerPrivate.h | 10 ++++--- dom/workers/WorkerScope.cpp | 3 ++- .../remoteworkers/RemoteWorkerChild.cpp | 2 +- .../remoteworkers/RemoteWorkerTypes.ipdlh | 3 ++- dom/workers/sharedworkers/SharedWorker.cpp | 6 +---- 12 files changed, 47 insertions(+), 51 deletions(-) diff --git a/dom/broadcastchannel/BroadcastChannel.cpp b/dom/broadcastchannel/BroadcastChannel.cpp index 230088b80480..89c2b678605f 100644 --- a/dom/broadcastchannel/BroadcastChannel.cpp +++ b/dom/broadcastchannel/BroadcastChannel.cpp @@ -229,6 +229,8 @@ already_AddRefed BroadcastChannel::Constructor( nsAutoCString origin; PrincipalInfo principalInfo; + nsContentUtils::StorageAccess storageAccess; + if (NS_IsMainThread()) { nsCOMPtr window = do_QueryInterface(global); if (NS_WARN_IF(!window)) { @@ -249,14 +251,6 @@ already_AddRefed BroadcastChannel::Constructor( return nullptr; } - // We want to allow opaque origins. - if (!principal->GetIsNullPrincipal() && - nsContentUtils::StorageAllowedForWindow(window) <= - nsContentUtils::StorageAccess::eDeny) { - aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); - return nullptr; - } - aRv = principal->GetOrigin(origin); if (NS_WARN_IF(aRv.Failed())) { return nullptr; @@ -266,6 +260,8 @@ already_AddRefed BroadcastChannel::Constructor( if (NS_WARN_IF(aRv.Failed())) { return nullptr; } + + storageAccess = nsContentUtils::StorageAllowedForWindow(window); } else { JSContext* cx = aGlobal.Context(); @@ -290,15 +286,17 @@ already_AddRefed BroadcastChannel::Constructor( return nullptr; } - if (principalInfo.type() != PrincipalInfo::TNullPrincipalInfo && - !workerPrivate->IsStorageAllowed()) { - aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); - return nullptr; - } - + storageAccess = workerPrivate->StorageAccess(); bc->mWorkerRef = std::move(workerRef); } + // We want to allow opaque origins. + if (principalInfo.type() != PrincipalInfo::TNullPrincipalInfo && + storageAccess <= nsContentUtils::StorageAccess::eDeny) { + aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); + return nullptr; + } + // Register this component to PBackground. PBackgroundChild* actorChild = BackgroundChild::GetOrCreateForCurrentThread(); if (NS_WARN_IF(!actorChild)) { diff --git a/dom/cache/CacheStorage.cpp b/dom/cache/CacheStorage.cpp index 99f0f8949279..24598a98bc5e 100644 --- a/dom/cache/CacheStorage.cpp +++ b/dom/cache/CacheStorage.cpp @@ -567,21 +567,23 @@ OpenMode CacheStorage::GetOpenMode() const { bool CacheStorage::HasStorageAccess() const { NS_ASSERT_OWNINGTHREAD(CacheStorage); + nsContentUtils::StorageAccess access; + if (NS_IsMainThread()) { nsCOMPtr window = do_QueryInterface(mGlobal); if (NS_WARN_IF(!window)) { return true; } - nsContentUtils::StorageAccess access = - nsContentUtils::StorageAllowedForWindow(window); - return access > nsContentUtils::StorageAccess::ePrivateBrowsing; + access = nsContentUtils::StorageAllowedForWindow(window); + } else { + WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); + MOZ_ASSERT(workerPrivate); + + access = workerPrivate->StorageAccess(); } - WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); - MOZ_ASSERT(workerPrivate); - - return workerPrivate->IsStorageAllowed(); + return access > nsContentUtils::StorageAccess::ePrivateBrowsing; } } // namespace cache diff --git a/dom/clients/manager/ClientSource.cpp b/dom/clients/manager/ClientSource.cpp index 4df62090bae5..a66059e5185d 100644 --- a/dom/clients/manager/ClientSource.cpp +++ b/dom/clients/manager/ClientSource.cpp @@ -206,7 +206,8 @@ void ClientSource::WorkerExecutionReady(WorkerPrivate* aWorkerPrivate) { // execution ready. We can't reliably determine what our storage policy // is before execution ready, unfortunately. if (mController.isSome()) { - MOZ_DIAGNOSTIC_ASSERT(aWorkerPrivate->IsStorageAllowed() || + MOZ_DIAGNOSTIC_ASSERT(aWorkerPrivate->StorageAccess() > + nsContentUtils::StorageAccess::ePrivateBrowsing || StringBeginsWith(aWorkerPrivate->ScriptURL(), NS_LITERAL_STRING("blob:"))); } @@ -380,7 +381,8 @@ void ClientSource::SetController( nsContentUtils::StorageAllowedForWindow(GetInnerWindow()) == nsContentUtils::StorageAccess::eAllow); } else if (GetWorkerPrivate()) { - MOZ_DIAGNOSTIC_ASSERT(GetWorkerPrivate()->IsStorageAllowed() || + MOZ_DIAGNOSTIC_ASSERT(GetWorkerPrivate()->StorageAccess() > + nsContentUtils::StorageAccess::ePrivateBrowsing || StringBeginsWith(GetWorkerPrivate()->ScriptURL(), NS_LITERAL_STRING("blob:"))); } @@ -435,7 +437,8 @@ RefPtr ClientSource::Control( nsContentUtils::StorageAccess::eAllow; } else if (GetWorkerPrivate()) { // Local URL workers and workers with access to storage cna be controlled. - controlAllowed = GetWorkerPrivate()->IsStorageAllowed() || + controlAllowed = GetWorkerPrivate()->StorageAccess() > + nsContentUtils::StorageAccess::ePrivateBrowsing || StringBeginsWith(GetWorkerPrivate()->ScriptURL(), NS_LITERAL_STRING("blob:")); } @@ -648,13 +651,7 @@ nsresult ClientSource::SnapshotState(ClientState* aStateOut) { return NS_ERROR_DOM_INVALID_STATE_ERR; } - // Workers only keep a boolean for storage access at the moment. - // Map this back to eAllow or eDeny for now. - nsContentUtils::StorageAccess storage = - workerPrivate->IsStorageAllowed() ? nsContentUtils::StorageAccess::eAllow - : nsContentUtils::StorageAccess::eDeny; - - *aStateOut = ClientState(ClientWorkerState(storage)); + *aStateOut = ClientState(ClientWorkerState(workerPrivate->StorageAccess())); return NS_OK; } diff --git a/dom/serviceworkers/ServiceWorkerPrivate.cpp b/dom/serviceworkers/ServiceWorkerPrivate.cpp index 5953f978b51e..6d494612c8e7 100644 --- a/dom/serviceworkers/ServiceWorkerPrivate.cpp +++ b/dom/serviceworkers/ServiceWorkerPrivate.cpp @@ -1729,10 +1729,8 @@ nsresult ServiceWorkerPrivate::SpawnWorkerIfNeeded(WakeUpReason aWhy, } info.mLoadingPrincipal = info.mPrincipal; - nsContentUtils::StorageAccess access = + info.mStorageAccess = nsContentUtils::StorageAllowedForServiceWorker(info.mPrincipal); - info.mStorageAllowed = - access > nsContentUtils::StorageAccess::ePrivateBrowsing; info.mCookieSettings = mozilla::net::CookieSettings::Create(); MOZ_ASSERT(info.mCookieSettings); diff --git a/dom/workers/WorkerLoadInfo.cpp b/dom/workers/WorkerLoadInfo.cpp index ea6a57ced5a0..6d028349f090 100644 --- a/dom/workers/WorkerLoadInfo.cpp +++ b/dom/workers/WorkerLoadInfo.cpp @@ -87,7 +87,7 @@ WorkerLoadInfoData::WorkerLoadInfoData() mReportCSPViolations(false), mXHRParamsAllowed(false), mPrincipalIsSystem(false), - mStorageAllowed(false), + mStorageAccess(nsContentUtils::StorageAccess::eDeny), mFirstPartyStorageAccessGranted(false), mServiceWorkersTestingInWindow(false), mSecureContext(eNotSet) {} diff --git a/dom/workers/WorkerLoadInfo.h b/dom/workers/WorkerLoadInfo.h index 08083b9d306b..49dcea544542 100644 --- a/dom/workers/WorkerLoadInfo.h +++ b/dom/workers/WorkerLoadInfo.h @@ -112,7 +112,7 @@ struct WorkerLoadInfoData { bool mReportCSPViolations; bool mXHRParamsAllowed; bool mPrincipalIsSystem; - bool mStorageAllowed; + nsContentUtils::StorageAccess mStorageAccess; bool mFirstPartyStorageAccessGranted; bool mServiceWorkersTestingInWindow; OriginAttributes mOriginAttributes; diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp index 00f70bca0c16..28fcc8e1de8f 100644 --- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -2355,7 +2355,7 @@ nsresult WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindowInner* aWindow, loadInfo.mDomain = aParent->Domain(); loadInfo.mFromWindow = aParent->IsFromWindow(); loadInfo.mWindowID = aParent->WindowID(); - loadInfo.mStorageAllowed = aParent->IsStorageAllowed(); + loadInfo.mStorageAccess = aParent->StorageAccess(); loadInfo.mOriginAttributes = aParent->GetOriginAttributes(); loadInfo.mServiceWorkersTestingInWindow = aParent->ServiceWorkersTestingInWindow(); @@ -2482,9 +2482,8 @@ nsresult WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindowInner* aWindow, loadInfo.mFromWindow = true; loadInfo.mWindowID = globalWindow->WindowID(); - nsContentUtils::StorageAccess access = + loadInfo.mStorageAccess = nsContentUtils::StorageAllowedForWindow(globalWindow); - loadInfo.mStorageAllowed = access > nsContentUtils::StorageAccess::eDeny; loadInfo.mCookieSettings = document->CookieSettings(); loadInfo.mOriginAttributes = nsContentUtils::GetOriginAttributes(document); @@ -2530,7 +2529,7 @@ nsresult WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindowInner* aWindow, loadInfo.mXHRParamsAllowed = true; loadInfo.mFromWindow = false; loadInfo.mWindowID = UINT64_MAX; - loadInfo.mStorageAllowed = true; + loadInfo.mStorageAccess = nsContentUtils::StorageAccess::eAllow; loadInfo.mCookieSettings = mozilla::net::CookieSettings::Create(); MOZ_ASSERT(loadInfo.mCookieSettings); diff --git a/dom/workers/WorkerPrivate.h b/dom/workers/WorkerPrivate.h index 89a6a6811003..1b29f7f543a1 100644 --- a/dom/workers/WorkerPrivate.h +++ b/dom/workers/WorkerPrivate.h @@ -12,6 +12,7 @@ #include "mozilla/CondVar.h" #include "mozilla/DOMEventTargetHelper.h" #include "mozilla/RelativeTimeline.h" +#include "nsContentUtils.h" #include "nsIContentSecurityPolicy.h" #include "nsIEventTarget.h" #include "nsTObserverArray.h" @@ -728,10 +729,13 @@ class WorkerPrivate : public RelativeTimeline { mLoadInfo.mXHRParamsAllowed = aAllowed; } - bool IsStorageAllowed() const { + nsContentUtils::StorageAccess StorageAccess() const { AssertIsOnWorkerThread(); - return mLoadInfo.mStorageAllowed || - mLoadInfo.mFirstPartyStorageAccessGranted; + if (mLoadInfo.mFirstPartyStorageAccessGranted) { + return nsContentUtils::StorageAccess::eAllow; + } + + return mLoadInfo.mStorageAccess; } nsICookieSettings* CookieSettings() const { diff --git a/dom/workers/WorkerScope.cpp b/dom/workers/WorkerScope.cpp index 4a52b710055e..6ac4b5f3d29e 100644 --- a/dom/workers/WorkerScope.cpp +++ b/dom/workers/WorkerScope.cpp @@ -393,7 +393,8 @@ already_AddRefed WorkerGlobalScope::GetIndexedDB( RefPtr indexedDB = mIndexedDB; if (!indexedDB) { - if (!mWorkerPrivate->IsStorageAllowed()) { + if (mWorkerPrivate->StorageAccess() <= + nsContentUtils::StorageAccess::eDeny) { NS_WARNING("IndexedDB is not allowed in this worker!"); aErrorResult = NS_ERROR_DOM_SECURITY_ERR; return nullptr; diff --git a/dom/workers/remoteworkers/RemoteWorkerChild.cpp b/dom/workers/remoteworkers/RemoteWorkerChild.cpp index 569fb8035a39..90a0f2e8a664 100644 --- a/dom/workers/remoteworkers/RemoteWorkerChild.cpp +++ b/dom/workers/remoteworkers/RemoteWorkerChild.cpp @@ -271,7 +271,7 @@ nsresult RemoteWorkerChild::ExecWorkerOnMainThread( info.mDomain = aData.domain(); info.mPrincipal = principal; info.mLoadingPrincipal = loadingPrincipal; - info.mStorageAllowed = aData.isStorageAccessAllowed(); + info.mStorageAccess = aData.storageAccess(); info.mOriginAttributes = BasePrincipal::Cast(principal)->OriginAttributesRef(); info.mCookieSettings = net::CookieSettings::Create(); diff --git a/dom/workers/remoteworkers/RemoteWorkerTypes.ipdlh b/dom/workers/remoteworkers/RemoteWorkerTypes.ipdlh index 3d4e7725cfbf..1078443d7d48 100644 --- a/dom/workers/remoteworkers/RemoteWorkerTypes.ipdlh +++ b/dom/workers/remoteworkers/RemoteWorkerTypes.ipdlh @@ -7,6 +7,7 @@ include PBackgroundSharedTypes; include URIParams; using struct mozilla::void_t from "ipc/IPCMessageUtils.h"; +using nsContentUtils::StorageAccess from "mozilla/dom/ClientIPCUtils.h"; namespace mozilla { namespace dom { @@ -43,7 +44,7 @@ struct RemoteWorkerData IPCClientInfo? clientInfo; - bool isStorageAccessAllowed; + StorageAccess storageAccess; bool isSharedWorker; }; diff --git a/dom/workers/sharedworkers/SharedWorker.cpp b/dom/workers/sharedworkers/SharedWorker.cpp index 1c50be1da3f0..b40e501ec34c 100644 --- a/dom/workers/sharedworkers/SharedWorker.cpp +++ b/dom/workers/sharedworkers/SharedWorker.cpp @@ -204,15 +204,11 @@ already_AddRefed SharedWorker::Constructor( ipcClientInfo.emplace(clientInfo.value().ToIPC()); } - bool storageAccessAllowed = - storageAllowed > nsContentUtils::StorageAccess::eDeny; - RemoteWorkerData remoteWorkerData( nsString(aScriptURL), baseURL, resolvedScriptURL, name, loadingPrincipalInfo, loadingPrincipalCSP, loadingPrincipalPreloadCSP, principalInfo, principalCSP, principalPreloadCSP, loadInfo.mDomain, - isSecureContext, ipcClientInfo, storageAccessAllowed, - true /* sharedWorker */); + isSecureContext, ipcClientInfo, storageAllowed, true /* sharedWorker */); PSharedWorkerChild* pActor = actorChild->SendPSharedWorkerConstructor( remoteWorkerData, loadInfo.mWindowID, portIdentifier);