Bug 1339823 Create a pristine principal in ServiceWorkerPrivate::SpawnWorkerIfNeeded(). r=baku
☠☠ backed out by 1fa61f7d1186 ☠ ☠
authorBen Kelly <ben@wanderview.com>
Mon, 20 Feb 2017 09:05:55 -0500
changeset 343897 59e30ba1b38fafefaf72865e43a9e3e969db6da5
parent 343896 be761d783526b43f4a1c3525e4dd7d54f3512d85
child 343898 9c5f58a4c7dd529126a0eb401af98633e7feec06
push id31391
push userphilringnalda@gmail.com
push dateTue, 21 Feb 2017 04:29:09 +0000
treeherdermozilla-central@d84beb192e57 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku
bugs1339823
milestone54.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 1339823 Create a pristine principal in ServiceWorkerPrivate::SpawnWorkerIfNeeded(). r=baku
dom/workers/ScriptLoader.cpp
dom/workers/ServiceWorkerManager.cpp
dom/workers/ServiceWorkerPrivate.cpp
--- a/dom/workers/ScriptLoader.cpp
+++ b/dom/workers/ScriptLoader.cpp
@@ -1204,39 +1204,38 @@ private:
                                      loadInfo.mScriptTextLength);
     if (NS_SUCCEEDED(rv) && IsMainWorkerScript()) {
       nsCOMPtr<nsIURI> finalURI;
       rv = NS_NewURI(getter_AddRefs(finalURI), loadInfo.mFullURL, nullptr, nullptr);
       if (NS_SUCCEEDED(rv)) {
         mWorkerPrivate->SetBaseURI(finalURI);
       }
 
-      nsILoadGroup* loadGroup = mWorkerPrivate->GetLoadGroup();
-      MOZ_DIAGNOSTIC_ASSERT(loadGroup);
-
 #if defined(DEBUG) || !defined(RELEASE_OR_BETA)
       nsIPrincipal* principal = mWorkerPrivate->GetPrincipal();
       MOZ_DIAGNOSTIC_ASSERT(principal);
 
       bool equal = false;
       MOZ_ALWAYS_SUCCEEDS(responsePrincipal->Equals(principal, &equal));
       MOZ_DIAGNOSTIC_ASSERT(equal);
 
       nsCOMPtr<nsIContentSecurityPolicy> csp;
       MOZ_ALWAYS_SUCCEEDS(responsePrincipal->GetCsp(getter_AddRefs(csp)));
       MOZ_DIAGNOSTIC_ASSERT(!csp);
 #endif
 
       mWorkerPrivate->InitChannelInfo(aChannelInfo);
 
-      // Override the principal on the WorkerPrivate.  We just asserted that
-      // this is the same as our current WorkerPrivate principal, so this is
-      // almost a no-op.  We must do, it though, in order to avoid accidentally
-      // propagating the CSP object back to the ServiceWorkerRegistration
-      // principal.  If bug 965637 is fixed then this can be removed.
+      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.
       rv = mWorkerPrivate->SetPrincipalOnMainThread(responsePrincipal, loadGroup);
       MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
 
       rv = mWorkerPrivate->SetCSPFromHeaderValues(aCSPHeaderValue,
                                                   aCSPReportOnlyHeaderValue);
       MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
     }
 
--- a/dom/workers/ServiceWorkerManager.cpp
+++ b/dom/workers/ServiceWorkerManager.cpp
@@ -3214,45 +3214,18 @@ ServiceWorkerManager::CreateNewRegistrat
   rv = NS_NewURI(getter_AddRefs(scopeURI), aScope, nullptr, nullptr);
   MOZ_ASSERT(NS_SUCCEEDED(rv));
 
   RefPtr<ServiceWorkerRegistrationInfo> tmp =
     GetRegistration(aPrincipal, aScope);
   MOZ_ASSERT(!tmp);
 #endif
 
-  // The environment that registers the document may have some CSP applied
-  // to its principal.  This should not be inherited by the registration
-  // itself or the worker it creates.  To avoid confusion in callsites
-  // downstream we strip the CSP from the principal now.
-  //
-  // Unfortunately there is no API to clone a principal without its CSP.  To
-  // achieve the same thing we serialize to the IPC PrincipalInfo type and
-  // back to an nsIPrincipal.
-  PrincipalInfo principalInfo;
-  rv = PrincipalToPrincipalInfo(aPrincipal, &principalInfo);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return nullptr;
-  }
-
-  nsCOMPtr<nsIPrincipal> cleanPrincipal =
-    PrincipalInfoToPrincipal(principalInfo, &rv);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return nullptr;
-  }
-
-  // Verify that we do not have any CSP set on our principal "clone".
-#if defined(DEBUG) || !defined(RELEASE_OR_BETA)
-  nsCOMPtr<nsIContentSecurityPolicy> csp;
-  MOZ_ALWAYS_SUCCEEDS(cleanPrincipal->GetCsp(getter_AddRefs(csp)));
-  MOZ_DIAGNOSTIC_ASSERT(!csp);
-#endif
-
   RefPtr<ServiceWorkerRegistrationInfo> registration =
-    new ServiceWorkerRegistrationInfo(aScope, cleanPrincipal, aLoadFlags);
+    new ServiceWorkerRegistrationInfo(aScope, aPrincipal, aLoadFlags);
   // From now on ownership of registration is with
   // mServiceWorkerRegistrationInfos.
   AddScopeAndRegistration(aScope, registration);
   return registration.forget();
 }
 
 void
 ServiceWorkerManager::MaybeRemoveRegistration(ServiceWorkerRegistrationInfo* aRegistration)
--- a/dom/workers/ServiceWorkerPrivate.cpp
+++ b/dom/workers/ServiceWorkerPrivate.cpp
@@ -1731,33 +1731,45 @@ ServiceWorkerPrivate::SpawnWorkerIfNeede
   info.mLoadFlags = mInfo->GetLoadFlags() |
                     nsIChannel::LOAD_BYPASS_SERVICE_WORKER;
 
   rv = info.mBaseURI->GetHost(info.mDomain);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
-  info.mPrincipal = mInfo->GetPrincipal();
+  nsCOMPtr<nsIURI> uri;
+  rv = mInfo->GetPrincipal()->GetURI(getter_AddRefs(uri));
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  if (NS_WARN_IF(!uri)) {
+    return NS_ERROR_FAILURE;
+  }
+
+  // Create a pristine codebase principal to avoid any possibility of inheriting
+  // CSP values.  The principal on the registration may be polluted with CSP
+  // from the registering page or other places the principal is passed.  If
+  // bug 965637 is ever fixed this can be removed.
+  info.mPrincipal =
+    BasePrincipal::CreateCodebasePrincipal(uri, mInfo->GetOriginAttributes());
+  if (NS_WARN_IF(!info.mPrincipal)) {
+    return NS_ERROR_FAILURE;
+  }
 
   nsContentUtils::StorageAccess access =
     nsContentUtils::StorageAllowedForPrincipal(info.mPrincipal);
   info.mStorageAllowed = access > nsContentUtils::StorageAccess::ePrivateBrowsing;
   info.mOriginAttributes = mInfo->GetOriginAttributes();
 
-  // The ServiceWorkerRegistration principal should never have any CSP
-  // set.  The CSP from the page that registered the SW should not be
-  // inherited.  Verify this is the case in non-release builds
+  // Verify that we don't have any CSP on pristine principal.
 #if defined(DEBUG) || !defined(RELEASE_OR_BETA)
   nsCOMPtr<nsIContentSecurityPolicy> csp;
-  rv = info.mPrincipal->GetCsp(getter_AddRefs(csp));
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
+  Unused << info.mPrincipal->GetCsp(getter_AddRefs(csp));
   MOZ_DIAGNOSTIC_ASSERT(!csp);
 #endif
 
   // 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;