Bug 1536411 - StoragePrincipal - part 2 - Worker and StoragePrincipal, r=Ehsan
authorAndrea Marchesini <amarchesini@mozilla.com>
Fri, 12 Apr 2019 05:31:25 +0000
changeset 469235 382b8c528545e55f11deb83bc7bff63958f2b45e
parent 469234 4191e4de46ca8b9956de802aa68d197cec8a8f85
child 469236 5b98a535f40d9036cf3f2db281393f3b4ed41877
push id112776
push usershindli@mozilla.com
push dateFri, 12 Apr 2019 16:20:17 +0000
treeherdermozilla-inbound@b4501ced5619 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersEhsan
bugs1536411
milestone68.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
Bug 1536411 - StoragePrincipal - part 2 - Worker and StoragePrincipal, r=Ehsan Differential Revision: https://phabricator.services.mozilla.com/D24026
dom/serviceworkers/ServiceWorkerPrivate.cpp
dom/workers/ScriptLoader.cpp
dom/workers/WorkerLoadInfo.cpp
dom/workers/WorkerLoadInfo.h
dom/workers/WorkerPrivate.cpp
dom/workers/WorkerPrivate.h
dom/workers/remoteworkers/RemoteWorkerChild.cpp
dom/workers/remoteworkers/RemoteWorkerTypes.ipdlh
dom/workers/sharedworkers/SharedWorker.cpp
--- a/dom/serviceworkers/ServiceWorkerPrivate.cpp
+++ b/dom/serviceworkers/ServiceWorkerPrivate.cpp
@@ -1746,17 +1746,18 @@ nsresult ServiceWorkerPrivate::SpawnWork
 
   // Default CSP permissions for now.  These will be overrided if necessary
   // based on the script CSP headers during load in ScriptLoader.
   info.mEvalAllowed = true;
   info.mReportCSPViolations = false;
 
   WorkerPrivate::OverrideLoadInfoLoadGroup(info, info.mPrincipal);
 
-  rv = info.SetPrincipalOnMainThread(info.mPrincipal, info.mLoadGroup);
+  rv = info.SetPrincipalsOnMainThread(info.mPrincipal, info.mStoragePrincipal,
+                                      info.mLoadGroup);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   AutoJSAPI jsapi;
   jsapi.Init();
   ErrorResult error;
   NS_ConvertUTF8toUTF16 scriptSpec(mInfo->ScriptSpec());
--- a/dom/workers/ScriptLoader.cpp
+++ b/dom/workers/ScriptLoader.cpp
@@ -1183,17 +1183,17 @@ class ScriptLoaderRunnable final : publi
       NS_ENSURE_TRUE(mWorkerPrivate->FinalChannelPrincipalIsValid(channel),
                      NS_ERROR_FAILURE);
 
       // However, we must still override the principal since the nsIPrincipal
       // URL may be different due to same-origin redirects.  Unfortunately this
       // URL must exactly match the final worker script URL in order to
       // properly set the referrer header on fetch/xhr requests.  If bug 1340694
       // is ever fixed this can be removed.
-      rv = mWorkerPrivate->SetPrincipalFromChannel(channel);
+      rv = mWorkerPrivate->SetPrincipalsFromChannel(channel);
       NS_ENSURE_SUCCESS(rv, rv);
 
       nsCOMPtr<nsIContentSecurityPolicy> csp = mWorkerPrivate->GetCSP();
       // We did inherit CSP in bug 1223647. If we do not already have a CSP, we
       // should get it from the HTTP headers on the worker script.
       if (StaticPrefs::security_csp_enable()) {
         if (!csp) {
           rv = mWorkerPrivate->SetCSPFromHeaderValues(tCspHeaderValue,
@@ -1291,18 +1291,19 @@ class ScriptLoaderRunnable final : publi
       nsILoadGroup* loadGroup = mWorkerPrivate->GetLoadGroup();
       MOZ_DIAGNOSTIC_ASSERT(loadGroup);
 
       // Override the principal on the WorkerPrivate.  This is only necessary
       // in order to get a principal with exactly the correct URL.  The fetch
       // referrer logic depends on the WorkerPrivate principal having a URL
       // that matches the worker script URL.  If bug 1340694 is ever fixed
       // this can be removed.
-      rv = mWorkerPrivate->SetPrincipalOnMainThread(responsePrincipal,
-                                                    loadGroup);
+      // TODO: storagePrincipal here?
+      rv = mWorkerPrivate->SetPrincipalsOnMainThread(
+          responsePrincipal, responsePrincipal, loadGroup);
       MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
 
       rv = mWorkerPrivate->SetCSPFromHeaderValues(aCSPHeaderValue,
                                                   aCSPReportOnlyHeaderValue);
       MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
 
       mWorkerPrivate->SetReferrerPolicyFromHeaderValue(
           aReferrerPolicyHeaderValue);
@@ -1836,17 +1837,17 @@ class ChannelGetterRunnable final : publ
     mResult = workerinternals::ChannelFromScriptURLMainThread(
         mLoadInfo.mLoadingPrincipal, parentDoc, mLoadInfo.mLoadGroup, url,
         clientInfo,
         // Nested workers are always dedicated.
         nsIContentPolicy::TYPE_INTERNAL_WORKER, mLoadInfo.mCookieSettings,
         getter_AddRefs(channel));
     NS_ENSURE_SUCCESS(mResult, true);
 
-    mResult = mLoadInfo.SetPrincipalFromChannel(channel);
+    mResult = mLoadInfo.SetPrincipalsFromChannel(channel);
     NS_ENSURE_SUCCESS(mResult, true);
 
     mLoadInfo.mChannel = channel.forget();
     return true;
   }
 
   nsresult GetResult() const { return mResult; }
 
--- a/dom/workers/WorkerLoadInfo.cpp
+++ b/dom/workers/WorkerLoadInfo.cpp
@@ -87,78 +87,96 @@ WorkerLoadInfoData::WorkerLoadInfoData()
       mReportCSPViolations(false),
       mXHRParamsAllowed(false),
       mPrincipalIsSystem(false),
       mStorageAccess(nsContentUtils::StorageAccess::eDeny),
       mFirstPartyStorageAccessGranted(false),
       mServiceWorkersTestingInWindow(false),
       mSecureContext(eNotSet) {}
 
-nsresult WorkerLoadInfo::SetPrincipalOnMainThread(nsIPrincipal* aPrincipal,
-                                                  nsILoadGroup* aLoadGroup) {
+nsresult WorkerLoadInfo::SetPrincipalsOnMainThread(
+    nsIPrincipal* aPrincipal, nsIPrincipal* aStoragePrincipal,
+    nsILoadGroup* aLoadGroup) {
   AssertIsOnMainThread();
   MOZ_ASSERT(NS_LoadGroupMatchesPrincipal(aLoadGroup, aPrincipal));
 
   mPrincipal = aPrincipal;
+  mStoragePrincipal = aStoragePrincipal;
   mPrincipalIsSystem = nsContentUtils::IsSystemPrincipal(aPrincipal);
 
   nsresult rv = aPrincipal->GetCsp(getter_AddRefs(mCSP));
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (mCSP) {
     mCSP->GetAllowsEval(&mReportCSPViolations, &mEvalAllowed);
   } else {
     mEvalAllowed = true;
     mReportCSPViolations = false;
   }
 
   mLoadGroup = aLoadGroup;
 
   mPrincipalInfo = new PrincipalInfo();
+  mStoragePrincipalInfo = new PrincipalInfo();
   mOriginAttributes = nsContentUtils::GetOriginAttributes(aLoadGroup);
 
   rv = PrincipalToPrincipalInfo(aPrincipal, mPrincipalInfo);
   NS_ENSURE_SUCCESS(rv, rv);
 
+  if (aPrincipal->Equals(aStoragePrincipal)) {
+    *mStoragePrincipalInfo = *mPrincipalInfo;
+  } else {
+    mStoragePrincipalInfo = new PrincipalInfo();
+    rv = PrincipalToPrincipalInfo(aStoragePrincipal, mStoragePrincipalInfo);
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+
   rv = nsContentUtils::GetUTFOrigin(aPrincipal, mOrigin);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
-nsresult WorkerLoadInfo::GetPrincipalAndLoadGroupFromChannel(
+nsresult WorkerLoadInfo::GetPrincipalsAndLoadGroupFromChannel(
     nsIChannel* aChannel, nsIPrincipal** aPrincipalOut,
-    nsILoadGroup** aLoadGroupOut) {
+    nsIPrincipal** aStoragePrincipalOut, nsILoadGroup** aLoadGroupOut) {
   AssertIsOnMainThread();
   MOZ_DIAGNOSTIC_ASSERT(aChannel);
   MOZ_DIAGNOSTIC_ASSERT(aPrincipalOut);
+  MOZ_DIAGNOSTIC_ASSERT(aStoragePrincipalOut);
   MOZ_DIAGNOSTIC_ASSERT(aLoadGroupOut);
 
   // Initial triggering principal should be set
   NS_ENSURE_TRUE(mLoadingPrincipal, NS_ERROR_DOM_INVALID_STATE_ERR);
 
   nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
   MOZ_DIAGNOSTIC_ASSERT(ssm);
 
   nsCOMPtr<nsIPrincipal> channelPrincipal;
   nsresult rv = ssm->GetChannelResultPrincipal(
       aChannel, getter_AddRefs(channelPrincipal));
   NS_ENSURE_SUCCESS(rv, rv);
 
+  nsCOMPtr<nsIPrincipal> channelStoragePrincipal;
+  rv = ssm->GetChannelResultStoragePrincipal(
+      aChannel, getter_AddRefs(channelStoragePrincipal));
+  NS_ENSURE_SUCCESS(rv, rv);
+
   // Every time we call GetChannelResultPrincipal() it will return a different
   // null principal for a data URL.  We don't want to change the worker's
   // principal again, though.  Instead just keep the original null principal we
   // first got from the channel.
   //
   // Note, we don't do this by setting principalToInherit on the channel's
   // load info because we don't yet have the first null principal when we
   // create the channel.
   if (mPrincipal && mPrincipal->GetIsNullPrincipal() &&
       channelPrincipal->GetIsNullPrincipal()) {
     channelPrincipal = mPrincipal;
+    channelStoragePrincipal = mPrincipal;
   }
 
   nsCOMPtr<nsILoadGroup> channelLoadGroup;
   rv = aChannel->GetLoadGroup(getter_AddRefs(channelLoadGroup));
   NS_ENSURE_SUCCESS(rv, rv);
   MOZ_ASSERT(channelLoadGroup);
 
   // If the loading principal is the system principal then the channel
@@ -181,51 +199,57 @@ nsresult WorkerLoadInfo::GetPrincipalAnd
       rv = NS_URIChainHasFlags(finalURI, nsIProtocolHandler::URI_IS_UI_RESOURCE,
                                &isResource);
       NS_ENSURE_SUCCESS(rv, rv);
 
       if (isResource) {
         // Assign the system principal to the resource:// worker only if it
         // was loaded from code using the system principal.
         channelPrincipal = mLoadingPrincipal;
+        channelStoragePrincipal = mLoadingPrincipal;
       } else {
         return NS_ERROR_DOM_BAD_URI;
       }
     }
   }
 
   // The principal can change, but it should still match the original
   // load group's appId and browser element flag.
   MOZ_ASSERT(NS_LoadGroupMatchesPrincipal(channelLoadGroup, channelPrincipal));
 
   channelPrincipal.forget(aPrincipalOut);
+  channelStoragePrincipal.forget(aStoragePrincipalOut);
   channelLoadGroup.forget(aLoadGroupOut);
 
   return NS_OK;
 }
 
-nsresult WorkerLoadInfo::SetPrincipalFromChannel(nsIChannel* aChannel) {
+nsresult WorkerLoadInfo::SetPrincipalsFromChannel(nsIChannel* aChannel) {
   AssertIsOnMainThread();
 
   nsCOMPtr<nsIPrincipal> principal;
+  nsCOMPtr<nsIPrincipal> storagePrincipal;
   nsCOMPtr<nsILoadGroup> loadGroup;
-  nsresult rv = GetPrincipalAndLoadGroupFromChannel(
-      aChannel, getter_AddRefs(principal), getter_AddRefs(loadGroup));
+  nsresult rv = GetPrincipalsAndLoadGroupFromChannel(
+      aChannel, getter_AddRefs(principal), getter_AddRefs(storagePrincipal),
+      getter_AddRefs(loadGroup));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  return SetPrincipalOnMainThread(principal, loadGroup);
+  return SetPrincipalsOnMainThread(principal, storagePrincipal, loadGroup);
 }
 
 bool WorkerLoadInfo::FinalChannelPrincipalIsValid(nsIChannel* aChannel) {
   AssertIsOnMainThread();
 
   nsCOMPtr<nsIPrincipal> principal;
+  nsCOMPtr<nsIPrincipal> storagePrincipal;
   nsCOMPtr<nsILoadGroup> loadGroup;
-  nsresult rv = GetPrincipalAndLoadGroupFromChannel(
-      aChannel, getter_AddRefs(principal), getter_AddRefs(loadGroup));
+  nsresult rv = GetPrincipalsAndLoadGroupFromChannel(
+      aChannel, getter_AddRefs(principal), getter_AddRefs(storagePrincipal),
+      getter_AddRefs(loadGroup));
   NS_ENSURE_SUCCESS(rv, false);
 
   // Verify that the channel is still a null principal.  We don't care
   // if these are the exact same null principal object, though.  From
   // the worker's perspective its the same effect.
   if (principal->GetIsNullPrincipal() && mPrincipal->GetIsNullPrincipal()) {
     return true;
   }
@@ -238,17 +262,20 @@ bool WorkerLoadInfo::FinalChannelPrincip
 
   return false;
 }
 
 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
 bool WorkerLoadInfo::PrincipalIsValid() const {
   return mPrincipal && mPrincipalInfo &&
          mPrincipalInfo->type() != PrincipalInfo::T__None &&
-         mPrincipalInfo->type() <= PrincipalInfo::T__Last;
+         mPrincipalInfo->type() <= PrincipalInfo::T__Last &&
+         mStoragePrincipal && mStoragePrincipalInfo &&
+         mStoragePrincipalInfo->type() != PrincipalInfo::T__None &&
+         mStoragePrincipalInfo->type() <= PrincipalInfo::T__Last;
 }
 
 bool WorkerLoadInfo::PrincipalURIMatchesScriptURL() {
   AssertIsOnMainThread();
 
   nsAutoCString scheme;
   nsresult rv = mBaseURI->GetScheme(scheme);
   NS_ENSURE_SUCCESS(rv, false);
@@ -307,24 +334,25 @@ bool WorkerLoadInfo::PrincipalURIMatches
 bool WorkerLoadInfo::ProxyReleaseMainThreadObjects(
     WorkerPrivate* aWorkerPrivate) {
   nsCOMPtr<nsILoadGroup> nullLoadGroup;
   return ProxyReleaseMainThreadObjects(aWorkerPrivate, nullLoadGroup);
 }
 
 bool WorkerLoadInfo::ProxyReleaseMainThreadObjects(
     WorkerPrivate* aWorkerPrivate, nsCOMPtr<nsILoadGroup>& aLoadGroupToCancel) {
-  static const uint32_t kDoomedCount = 10;
+  static const uint32_t kDoomedCount = 11;
   nsTArray<nsCOMPtr<nsISupports>> doomed(kDoomedCount);
 
   SwapToISupportsArray(mWindow, doomed);
   SwapToISupportsArray(mScriptContext, doomed);
   SwapToISupportsArray(mBaseURI, doomed);
   SwapToISupportsArray(mResolvedScriptURI, doomed);
   SwapToISupportsArray(mPrincipal, doomed);
+  SwapToISupportsArray(mStoragePrincipal, doomed);
   SwapToISupportsArray(mLoadingPrincipal, doomed);
   SwapToISupportsArray(mChannel, doomed);
   SwapToISupportsArray(mCSP, doomed);
   SwapToISupportsArray(mLoadGroup, doomed);
   SwapToISupportsArray(mInterfaceRequestor, doomed);
   // Before adding anything here update kDoomedCount above!
 
   MOZ_ASSERT(doomed.Length() == kDoomedCount);
--- a/dom/workers/WorkerLoadInfo.h
+++ b/dom/workers/WorkerLoadInfo.h
@@ -45,16 +45,17 @@ struct WorkerLoadInfoData {
   nsCOMPtr<nsIURI> mResolvedScriptURI;
 
   // This is the principal of the global (parent worker or a window) loading
   // the worker. It can be null if we are executing a ServiceWorker, otherwise,
   // except for data: URL, it must subsumes the worker principal.
   // If we load a data: URL, mPrincipal will be a null principal.
   nsCOMPtr<nsIPrincipal> mLoadingPrincipal;
   nsCOMPtr<nsIPrincipal> mPrincipal;
+  nsCOMPtr<nsIPrincipal> mStoragePrincipal;
 
   // Taken from the parent context.
   nsCOMPtr<nsICookieSettings> mCookieSettings;
 
   nsCOMPtr<nsIScriptContext> mScriptContext;
   nsCOMPtr<nsPIDOMWindowInner> mWindow;
   nsCOMPtr<nsIContentSecurityPolicy> mCSP;
   nsCOMPtr<nsIChannel> mChannel;
@@ -86,16 +87,17 @@ struct WorkerLoadInfoData {
     // actors alive for long after their ActorDestroy() methods are called.
     nsTArray<nsWeakPtr> mTabChildList;
   };
 
   // Only set if we have a custom overriden load group
   RefPtr<InterfaceRequestor> mInterfaceRequestor;
 
   nsAutoPtr<mozilla::ipc::PrincipalInfo> mPrincipalInfo;
+  nsAutoPtr<mozilla::ipc::PrincipalInfo> mStoragePrincipalInfo;
   nsCString mDomain;
   nsString mOrigin;  // Derived from mPrincipal; can be used on worker thread.
 
   nsString mServiceWorkerCacheName;
   Maybe<ServiceWorkerDescriptor> mServiceWorkerDescriptor;
   Maybe<ServiceWorkerRegistrationDescriptor>
       mServiceWorkerRegistrationDescriptor;
 
@@ -131,24 +133,25 @@ struct WorkerLoadInfoData {
 
 struct WorkerLoadInfo : WorkerLoadInfoData {
   WorkerLoadInfo();
   WorkerLoadInfo(WorkerLoadInfo&& aOther) noexcept;
   ~WorkerLoadInfo();
 
   WorkerLoadInfo& operator=(WorkerLoadInfo&& aOther) = default;
 
-  nsresult SetPrincipalOnMainThread(nsIPrincipal* aPrincipal,
-                                    nsILoadGroup* aLoadGroup);
+  nsresult SetPrincipalsOnMainThread(nsIPrincipal* aPrincipal,
+                                     nsIPrincipal* aStoragePrincipal,
+                                     nsILoadGroup* aLoadGroup);
 
-  nsresult GetPrincipalAndLoadGroupFromChannel(nsIChannel* aChannel,
-                                               nsIPrincipal** aPrincipalOut,
-                                               nsILoadGroup** aLoadGroupOut);
+  nsresult GetPrincipalsAndLoadGroupFromChannel(
+      nsIChannel* aChannel, nsIPrincipal** aPrincipalOut,
+      nsIPrincipal** aStoragePrincipalOut, nsILoadGroup** aLoadGroupOut);
 
-  nsresult SetPrincipalFromChannel(nsIChannel* aChannel);
+  nsresult SetPrincipalsFromChannel(nsIChannel* aChannel);
 
   bool FinalChannelPrincipalIsValid(nsIChannel* aChannel);
 
 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
   bool PrincipalIsValid() const;
 
   bool PrincipalURIMatchesScriptURL();
 #endif
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -1927,23 +1927,25 @@ void WorkerPrivate::SetBaseURI(nsIURI* a
     mLocationInfo.mHost.Assign(host);
   } else {
     mLocationInfo.mHost.Assign(mLocationInfo.mHostname);
   }
 
   nsContentUtils::GetUTFOrigin(aBaseURI, mLocationInfo.mOrigin);
 }
 
-nsresult WorkerPrivate::SetPrincipalOnMainThread(nsIPrincipal* aPrincipal,
-                                                 nsILoadGroup* aLoadGroup) {
-  return mLoadInfo.SetPrincipalOnMainThread(aPrincipal, aLoadGroup);
+nsresult WorkerPrivate::SetPrincipalsOnMainThread(
+    nsIPrincipal* aPrincipal, nsIPrincipal* aStoragePrincipal,
+    nsILoadGroup* aLoadGroup) {
+  return mLoadInfo.SetPrincipalsOnMainThread(aPrincipal, aStoragePrincipal,
+                                             aLoadGroup);
 }
 
-nsresult WorkerPrivate::SetPrincipalFromChannel(nsIChannel* aChannel) {
-  return mLoadInfo.SetPrincipalFromChannel(aChannel);
+nsresult WorkerPrivate::SetPrincipalsFromChannel(nsIChannel* aChannel) {
+  return mLoadInfo.SetPrincipalsFromChannel(aChannel);
 }
 
 bool WorkerPrivate::FinalChannelPrincipalIsValid(nsIChannel* aChannel) {
   return mLoadInfo.FinalChannelPrincipalIsValid(aChannel);
 }
 
 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
 bool WorkerPrivate::PrincipalURIMatchesScriptURL() {
@@ -2557,17 +2559,17 @@ nsresult WorkerPrivate::GetLoadInfo(JSCo
         clientInfo, ContentPolicyType(aWorkerType), loadInfo.mCookieSettings,
         getter_AddRefs(loadInfo.mChannel));
     NS_ENSURE_SUCCESS(rv, rv);
 
     rv = NS_GetFinalChannelURI(loadInfo.mChannel,
                                getter_AddRefs(loadInfo.mResolvedScriptURI));
     NS_ENSURE_SUCCESS(rv, rv);
 
-    rv = loadInfo.SetPrincipalFromChannel(loadInfo.mChannel);
+    rv = loadInfo.SetPrincipalsFromChannel(loadInfo.mChannel);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   MOZ_DIAGNOSTIC_ASSERT(loadInfo.mLoadingPrincipal);
   MOZ_DIAGNOSTIC_ASSERT(loadInfo.PrincipalIsValid());
 
   *aLoadInfo = std::move(loadInfo);
   return NS_OK;
--- a/dom/workers/WorkerPrivate.h
+++ b/dom/workers/WorkerPrivate.h
@@ -657,16 +657,21 @@ class WorkerPrivate : public RelativeTim
     mLoadInfo.mChannelInfo = aChannelInfo;
   }
 
   nsIPrincipal* GetPrincipal() const {
     AssertIsOnMainThread();
     return mLoadInfo.mPrincipal;
   }
 
+  nsIPrincipal* GetEffectiveStoragePrincipal() const {
+    AssertIsOnMainThread();
+    return mLoadInfo.mStoragePrincipal;
+  }
+
   nsIPrincipal* GetLoadingPrincipal() const {
     AssertIsOnMainThread();
     return mLoadInfo.mLoadingPrincipal;
   }
 
   const nsAString& Origin() const { return mLoadInfo.mOrigin; }
 
   nsILoadGroup* GetLoadGroup() const {
@@ -675,16 +680,20 @@ class WorkerPrivate : public RelativeTim
   }
 
   bool UsesSystemPrincipal() const { return mLoadInfo.mPrincipalIsSystem; }
 
   const mozilla::ipc::PrincipalInfo& GetPrincipalInfo() const {
     return *mLoadInfo.mPrincipalInfo;
   }
 
+  const mozilla::ipc::PrincipalInfo& GetEffectiveStoragePrincipalInfo() const {
+    return *mLoadInfo.mStoragePrincipalInfo;
+  }
+
   already_AddRefed<nsIChannel> ForgetWorkerChannel() {
     AssertIsOnMainThread();
     return mLoadInfo.mChannel.forget();
   }
 
   nsPIDOMWindowInner* GetWindow() {
     AssertIsOnMainThread();
     return mLoadInfo.mWindow;
@@ -783,20 +792,21 @@ class WorkerPrivate : public RelativeTim
       already_AddRefed<nsIRunnable> aRunnable);
 
   bool ProxyReleaseMainThreadObjects();
 
   void GarbageCollect(bool aShrinking);
 
   void CycleCollect(bool aDummy);
 
-  nsresult SetPrincipalOnMainThread(nsIPrincipal* aPrincipal,
-                                    nsILoadGroup* aLoadGroup);
+  nsresult SetPrincipalsOnMainThread(nsIPrincipal* aPrincipal,
+                                     nsIPrincipal* aStoragePrincipal,
+                                     nsILoadGroup* aLoadGroup);
 
-  nsresult SetPrincipalFromChannel(nsIChannel* aChannel);
+  nsresult SetPrincipalsFromChannel(nsIChannel* aChannel);
 
   bool FinalChannelPrincipalIsValid(nsIChannel* aChannel);
 
 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
   bool PrincipalURIMatchesScriptURL();
 #endif
 
   void UpdateOverridenLoadGroup(nsILoadGroup* aBaseLoadGroup);
--- a/dom/workers/remoteworkers/RemoteWorkerChild.cpp
+++ b/dom/workers/remoteworkers/RemoteWorkerChild.cpp
@@ -257,24 +257,39 @@ nsresult RemoteWorkerChild::ExecWorkerOn
 
   rv = PopulatePrincipalContentSecurityPolicy(
       loadingPrincipal, aData.loadingPrincipalCsp(),
       aData.loadingPrincipalPreloadCsp());
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
+  nsCOMPtr<nsIPrincipal> storagePrincipal =
+      PrincipalInfoToPrincipal(aData.storagePrincipalInfo(), &rv);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  rv = PopulatePrincipalContentSecurityPolicy(
+      storagePrincipal, aData.storagePrincipalCsp(),
+      aData.storagePrincipalPreloadCsp());
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
   WorkerLoadInfo info;
   info.mBaseURI = DeserializeURI(aData.baseScriptURL());
   info.mResolvedScriptURI = DeserializeURI(aData.resolvedScriptURL());
 
   info.mPrincipalInfo = new PrincipalInfo(aData.principalInfo());
+  info.mStoragePrincipalInfo = new PrincipalInfo(aData.storagePrincipalInfo());
 
   info.mDomain = aData.domain();
   info.mPrincipal = principal;
+  info.mStoragePrincipal = storagePrincipal;
   info.mLoadingPrincipal = loadingPrincipal;
   info.mStorageAccess = aData.storageAccess();
   info.mOriginAttributes =
       BasePrincipal::Cast(principal)->OriginAttributesRef();
   info.mCookieSettings = net::CookieSettings::Create();
 
   // Default CSP permissions for now.  These will be overrided if necessary
   // based on the script CSP headers during load in ScriptLoader.
@@ -285,17 +300,18 @@ nsresult RemoteWorkerChild::ExecWorkerOn
                             : WorkerLoadInfo::eInsecureContext;
 
   WorkerPrivate::OverrideLoadInfoLoadGroup(info, info.mLoadingPrincipal);
 
   RefPtr<SharedWorkerInterfaceRequestor> requestor =
       new SharedWorkerInterfaceRequestor();
   info.mInterfaceRequestor->SetOuterRequestor(requestor);
 
-  rv = info.SetPrincipalOnMainThread(info.mPrincipal, info.mLoadGroup);
+  rv = info.SetPrincipalsOnMainThread(info.mPrincipal, info.mStoragePrincipal,
+                                      info.mLoadGroup);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   Maybe<ClientInfo> clientInfo;
   if (aData.clientInfo().isSome()) {
     clientInfo.emplace(ClientInfo(aData.clientInfo().ref()));
   }
--- a/dom/workers/remoteworkers/RemoteWorkerTypes.ipdlh
+++ b/dom/workers/remoteworkers/RemoteWorkerTypes.ipdlh
@@ -33,16 +33,20 @@ struct RemoteWorkerData
   PrincipalInfo loadingPrincipalInfo;
   ContentSecurityPolicy[] loadingPrincipalCsp;
   ContentSecurityPolicy[] loadingPrincipalPreloadCsp;
 
   PrincipalInfo principalInfo;
   ContentSecurityPolicy[] principalCsp;
   ContentSecurityPolicy[] principalPreloadCsp;
 
+  PrincipalInfo storagePrincipalInfo;
+  ContentSecurityPolicy[] storagePrincipalCsp;
+  ContentSecurityPolicy[] storagePrincipalPreloadCsp;
+
   nsCString domain;
 
   bool isSecureContext;
 
   IPCClientInfo? clientInfo;
 
   StorageAccess storageAccess;
 
--- a/dom/workers/sharedworkers/SharedWorker.cpp
+++ b/dom/workers/sharedworkers/SharedWorker.cpp
@@ -171,16 +171,36 @@ already_AddRefed<SharedWorker> SharedWor
   nsTArray<ContentSecurityPolicy> loadingPrincipalPreloadCSP;
   aRv = PopulateContentSecurityPolicyArray(loadInfo.mLoadingPrincipal,
                                            loadingPrincipalCSP,
                                            loadingPrincipalPreloadCSP);
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
+  PrincipalInfo storagePrincipalInfo;
+  if (loadInfo.mPrincipal->Equals(loadInfo.mStoragePrincipal)) {
+    storagePrincipalInfo = principalInfo;
+  } else {
+    aRv = PrincipalToPrincipalInfo(loadInfo.mStoragePrincipal,
+                                   &storagePrincipalInfo);
+    if (NS_WARN_IF(aRv.Failed())) {
+      return nullptr;
+    }
+  }
+
+  nsTArray<ContentSecurityPolicy> storagePrincipalCSP;
+  nsTArray<ContentSecurityPolicy> storagePrincipalPreloadCSP;
+  aRv = PopulateContentSecurityPolicyArray(loadInfo.mStoragePrincipal,
+                                           storagePrincipalCSP,
+                                           storagePrincipalPreloadCSP);
+  if (NS_WARN_IF(aRv.Failed())) {
+    return nullptr;
+  }
+
   // We don't actually care about this MessageChannel, but we use it to 'steal'
   // its 2 connected ports.
   nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(window);
   RefPtr<MessageChannel> channel = MessageChannel::Constructor(global, aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
@@ -202,17 +222,18 @@ already_AddRefed<SharedWorker> SharedWor
   Maybe<ClientInfo> clientInfo = window->GetClientInfo();
   if (clientInfo.isSome()) {
     ipcClientInfo.emplace(clientInfo.value().ToIPC());
   }
 
   RemoteWorkerData remoteWorkerData(
       nsString(aScriptURL), baseURL, resolvedScriptURL, name,
       loadingPrincipalInfo, loadingPrincipalCSP, loadingPrincipalPreloadCSP,
-      principalInfo, principalCSP, principalPreloadCSP, loadInfo.mDomain,
+      principalInfo, principalCSP, principalPreloadCSP, storagePrincipalInfo,
+      storagePrincipalCSP, storagePrincipalPreloadCSP, loadInfo.mDomain,
       isSecureContext, ipcClientInfo, storageAllowed, true /* sharedWorker */);
 
   PSharedWorkerChild* pActor = actorChild->SendPSharedWorkerConstructor(
       remoteWorkerData, loadInfo.mWindowID, portIdentifier);
 
   RefPtr<SharedWorkerChild> actor = static_cast<SharedWorkerChild*>(pActor);
   MOZ_ASSERT(actor);