Bug 1436812 P6 Move the NS_CheckContentLoadPolicy() from ServiceWorkerManager to ServiceWorkerContainer. r=baku
authorBen Kelly <ben@wanderview.com>
Mon, 23 Apr 2018 09:46:54 -0700
changeset 468659 2f27625fd5117e193980882ef5869be79cd39d30
parent 468658 06082fbb04cedca278b2581581873c5a5aa30d78
child 468660 16ddf190ca51b6bc7e5000f4573d41394f89f0dc
push id9165
push userasasaki@mozilla.com
push dateThu, 26 Apr 2018 21:04:54 +0000
treeherdermozilla-beta@064c3804de2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku
bugs1436812
milestone61.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 1436812 P6 Move the NS_CheckContentLoadPolicy() from ServiceWorkerManager to ServiceWorkerContainer. r=baku
dom/serviceworkers/ServiceWorkerContainer.cpp
dom/serviceworkers/ServiceWorkerManager.cpp
--- a/dom/serviceworkers/ServiceWorkerContainer.cpp
+++ b/dom/serviceworkers/ServiceWorkerContainer.cpp
@@ -1,29 +1,31 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ServiceWorkerContainer.h"
 
+#include "nsContentPolicyUtils.h"
 #include "nsContentSecurityManager.h"
 #include "nsContentUtils.h"
 #include "nsIDocument.h"
 #include "nsIServiceWorkerManager.h"
 #include "nsIScriptError.h"
 #include "nsIURL.h"
 #include "nsNetUtil.h"
 #include "nsPIDOMWindow.h"
 #include "mozilla/Services.h"
 
 #include "nsCycleCollectionParticipant.h"
 #include "nsServiceManagerUtils.h"
 
+#include "mozilla/LoadInfo.h"
 #include "mozilla/dom/DOMPrefs.h"
 #include "mozilla/dom/Navigator.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/ServiceWorker.h"
 #include "mozilla/dom/ServiceWorkerContainerBinding.h"
 
 #include "ServiceWorker.h"
 #include "ServiceWorkerContainerImpl.h"
@@ -293,16 +295,46 @@ ServiceWorkerContainer::Register(const n
   }
 
   if (!authenticatedOrigin) {
     NS_WARNING("ServiceWorker registration from insecure websites is not allowed.");
     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     return nullptr;
   }
 
+  // The next section of code executes an NS_CheckContentLoadPolicy()
+  // check.  This is necessary to enforce the CSP of the calling client.
+  // Currently this requires an nsIDocument.  Once bug 965637 lands we
+  // should try to move this into ServiceWorkerScopeAndScriptAreValid()
+  // using the ClientInfo instead of doing a window-specific check here.
+  // See bug 1455077 for further investigation.
+  nsCOMPtr<nsILoadInfo> secCheckLoadInfo =
+    new LoadInfo(doc->NodePrincipal(), // loading principal
+                 doc->NodePrincipal(), // triggering principal
+                 doc,                  // loading node
+                 nsILoadInfo::SEC_ONLY_FOR_EXPLICIT_CONTENTSEC_CHECK,
+                 nsIContentPolicy::TYPE_INTERNAL_SERVICE_WORKER);
+
+  // Check content policy.
+  int16_t decision = nsIContentPolicy::ACCEPT;
+  rv = NS_CheckContentLoadPolicy(scriptURI,
+                                 secCheckLoadInfo,
+                                 NS_LITERAL_CSTRING("application/javascript"),
+                                 &decision);
+  if (NS_FAILED(rv)) {
+    aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
+    return nullptr;
+
+  }
+  if (NS_WARN_IF(decision != nsIContentPolicy::ACCEPT)) {
+    aRv.Throw(NS_ERROR_CONTENT_BLOCKED);
+    return nullptr;
+  }
+
+
   // The spec says that the "client" passed to Register() must be the global
   // where the ServiceWorkerContainer was retrieved from.
   aRv = swm->Register(GetOwner(), scopeURI, scriptURI,
                       static_cast<uint16_t>(aOptions.mUpdateViaCache),
                       getter_AddRefs(promise));
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
--- a/dom/serviceworkers/ServiceWorkerManager.cpp
+++ b/dom/serviceworkers/ServiceWorkerManager.cpp
@@ -58,17 +58,16 @@
 #include "mozilla/dom/WorkerScope.h"
 #include "mozilla/ipc/BackgroundChild.h"
 #include "mozilla/ipc/PBackgroundChild.h"
 #include "mozilla/ipc/PBackgroundSharedTypes.h"
 #include "mozilla/dom/ScriptLoader.h"
 #include "mozilla/Unused.h"
 #include "mozilla/EnumSet.h"
 
-#include "nsContentPolicyUtils.h"
 #include "nsContentUtils.h"
 #include "nsNetUtil.h"
 #include "nsProxyRelease.h"
 #include "nsQueryObject.h"
 #include "nsTArray.h"
 
 #include "ServiceWorker.h"
 #include "ServiceWorkerContainer.h"
@@ -792,35 +791,16 @@ ServiceWorkerManager::Register(mozIDOMWi
   nsCOMPtr<nsIPrincipal> documentPrincipal = doc->NodePrincipal();
 
   nsresult rv = documentPrincipal->CheckMayLoad(aScriptURI, true /* report */,
                                                 false /* allowIfInheritsPrincipal */);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
-  nsCOMPtr<nsILoadInfo> secCheckLoadInfo =
-    new LoadInfo(documentPrincipal, // loading principal
-                 documentPrincipal, // triggering principal
-                 doc,
-                 nsILoadInfo::SEC_ONLY_FOR_EXPLICIT_CONTENTSEC_CHECK,
-                 nsIContentPolicy::TYPE_INTERNAL_SERVICE_WORKER);
-
-  // Check content policy.
-  int16_t decision = nsIContentPolicy::ACCEPT;
-  rv = NS_CheckContentLoadPolicy(aScriptURI,
-                                 secCheckLoadInfo,
-                                 EmptyCString(),
-                                 &decision);
-  NS_ENSURE_SUCCESS(rv, rv);
-  if (NS_WARN_IF(decision != nsIContentPolicy::ACCEPT)) {
-    return NS_ERROR_CONTENT_BLOCKED;
-  }
-
-
   rv = documentPrincipal->CheckMayLoad(aScopeURI, true /* report */,
                                        false /* allowIfInheritsPrinciple */);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   // The IsOriginPotentiallyTrustworthy() check allows file:// and possibly other
   // URI schemes.  We need to explicitly only allows http and https schemes.