Bug 1525006 - Add a new internal ContentPolicyType for ES6 modules. r=ckerschb
authorTom Schuster <evilpies@gmail.com>
Tue, 12 Feb 2019 13:16:32 +0000
changeset 458732 64ba51db91e8
parent 458675 a273edea702d
child 458733 67ac511f5c6c
push id35548
push useropoprus@mozilla.com
push dateWed, 13 Feb 2019 09:48:26 +0000
treeherdermozilla-central@93e37c529818 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersckerschb
bugs1525006
milestone67.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 1525006 - Add a new internal ContentPolicyType for ES6 modules. r=ckerschb Differential Revision: https://phabricator.services.mozilla.com/D19269
dom/base/nsContentPolicyUtils.h
dom/base/nsContentUtils.cpp
dom/base/nsContentUtils.h
dom/base/nsIContentPolicy.idl
dom/cache/DBSchema.cpp
dom/fetch/InternalRequest.cpp
dom/fetch/InternalRequest.h
dom/script/ScriptLoader.cpp
dom/script/ScriptLoader.h
dom/security/nsCSPUtils.cpp
extensions/permissions/nsContentBlocker.cpp
netwerk/base/nsINetworkInterceptController.idl
netwerk/protocol/http/nsHttpChannel.cpp
--- a/dom/base/nsContentPolicyUtils.h
+++ b/dom/base/nsContentPolicyUtils.h
@@ -130,16 +130,18 @@ inline const char *NS_CP_ContentTypeName
     CASE_RETURN(TYPE_INTERNAL_IMAGE);
     CASE_RETURN(TYPE_INTERNAL_IMAGE_PRELOAD);
     CASE_RETURN(TYPE_INTERNAL_IMAGE_FAVICON);
     CASE_RETURN(TYPE_INTERNAL_STYLESHEET);
     CASE_RETURN(TYPE_INTERNAL_STYLESHEET_PRELOAD);
     CASE_RETURN(TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS);
     CASE_RETURN(TYPE_SAVEAS_DOWNLOAD);
     CASE_RETURN(TYPE_SPECULATIVE);
+    CASE_RETURN(TYPE_INTERNAL_MODULE);
+    CASE_RETURN(TYPE_INTERNAL_MODULE_PRELOAD);
     default:
       return "<Unknown Type>";
   }
 }
 
 #undef CASE_RETURN
 
 /* Passes on parameters from its "caller"'s context. */
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -7986,16 +7986,17 @@ already_AddRefed<nsPIWindowRoot> nsConte
     }
   }
   return nullptr;
 }
 
 /* static */
 bool nsContentUtils::IsPreloadType(nsContentPolicyType aType) {
   return (aType == nsIContentPolicy::TYPE_INTERNAL_SCRIPT_PRELOAD ||
+          aType == nsIContentPolicy::TYPE_INTERNAL_MODULE_PRELOAD ||
           aType == nsIContentPolicy::TYPE_INTERNAL_IMAGE_PRELOAD ||
           aType == nsIContentPolicy::TYPE_INTERNAL_STYLESHEET_PRELOAD);
 }
 
 /* static */
 bool nsContentUtils::IsUpgradableDisplayType(nsContentPolicyType aType) {
   MOZ_ASSERT(NS_IsMainThread());
   return (aType == nsIContentPolicy::TYPE_IMAGE ||
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -3498,16 +3498,18 @@ class nsContentUtils {
   static uint32_t sInnerOrOuterWindowSerialCounter;
 };
 
 /* static */ inline nsContentPolicyType
 nsContentUtils::InternalContentPolicyTypeToExternal(nsContentPolicyType aType) {
   switch (aType) {
     case nsIContentPolicy::TYPE_INTERNAL_SCRIPT:
     case nsIContentPolicy::TYPE_INTERNAL_SCRIPT_PRELOAD:
+    case nsIContentPolicy::TYPE_INTERNAL_MODULE:
+    case nsIContentPolicy::TYPE_INTERNAL_MODULE_PRELOAD:
     case nsIContentPolicy::TYPE_INTERNAL_WORKER:
     case nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER:
     case nsIContentPolicy::TYPE_INTERNAL_SERVICE_WORKER:
     case nsIContentPolicy::TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS:
       return nsIContentPolicy::TYPE_SCRIPT;
 
     case nsIContentPolicy::TYPE_INTERNAL_EMBED:
     case nsIContentPolicy::TYPE_INTERNAL_OBJECT:
--- a/dom/base/nsIContentPolicy.idl
+++ b/dom/base/nsIContentPolicy.idl
@@ -341,16 +341,34 @@ interface nsIContentPolicy : nsISupports
    */
   const nsContentPolicyType TYPE_SAVEAS_DOWNLOAD = 43;
 
   /**
    * Indicates a speculative connection.
    */
   const nsContentPolicyType TYPE_SPECULATIVE = 44;
 
+  /**
+   * Indicates an internal constant for ES6 module scripts
+   * loaded through script elements or an import statement.
+   *
+   * This will be mapped to TYPE_SCRIPT before being passed
+   * to content policy implementations.
+   */
+  const nsContentPolicyType TYPE_INTERNAL_MODULE = 45;
+
+  /**
+   * Indicates an internal constant for *preloaded* ES6 module scripts
+   * loaded through script elements or an import statement.
+   *
+   * This will be mapped to TYPE_SCRIPT before being passed
+   * to content policy implementations.
+   */
+  const nsContentPolicyType TYPE_INTERNAL_MODULE_PRELOAD = 46;
+
   /* When adding new content types, please update nsContentBlocker,
    * NS_CP_ContentTypeName, nsCSPContext, CSP_ContentTypeToDirective,
    * DoContentSecurityChecks, all nsIContentPolicy implementations, the
    * static_assert in dom/cache/DBSchema.cpp, ChannelWrapper.webidl,
    * ChannelWrapper.cpp, nsPermissionManager.cpp, and other things that are not
    * listed here that are related to nsIContentPolicy. */
 
   //////////////////////////////////////////////////////////////////////
--- a/dom/cache/DBSchema.cpp
+++ b/dom/cache/DBSchema.cpp
@@ -325,17 +325,19 @@ static_assert(nsIContentPolicy::TYPE_INV
                   nsIContentPolicy::TYPE_INTERNAL_SCRIPT_PRELOAD == 36 &&
                   nsIContentPolicy::TYPE_INTERNAL_IMAGE == 37 &&
                   nsIContentPolicy::TYPE_INTERNAL_IMAGE_PRELOAD == 38 &&
                   nsIContentPolicy::TYPE_INTERNAL_STYLESHEET == 39 &&
                   nsIContentPolicy::TYPE_INTERNAL_STYLESHEET_PRELOAD == 40 &&
                   nsIContentPolicy::TYPE_INTERNAL_IMAGE_FAVICON == 41 &&
                   nsIContentPolicy::TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS == 42 &&
                   nsIContentPolicy::TYPE_SAVEAS_DOWNLOAD == 43 &&
-                  nsIContentPolicy::TYPE_SPECULATIVE == 44,
+                  nsIContentPolicy::TYPE_SPECULATIVE == 44 &&
+                  nsIContentPolicy::TYPE_INTERNAL_MODULE == 45 &&
+                  nsIContentPolicy::TYPE_INTERNAL_MODULE_PRELOAD == 46,
               "nsContentPolicyType values are as expected");
 
 namespace {
 
 typedef int32_t EntryId;
 
 struct IdCount {
   explicit IdCount(int32_t aId) : mId(aId), mCount(1) {}
--- a/dom/fetch/InternalRequest.cpp
+++ b/dom/fetch/InternalRequest.cpp
@@ -189,16 +189,18 @@ InternalRequest::MapContentPolicyTypeToR
     nsContentPolicyType aContentPolicyType) {
   RequestDestination destination = RequestDestination::_empty;
   switch (aContentPolicyType) {
     case nsIContentPolicy::TYPE_OTHER:
       destination = RequestDestination::_empty;
       break;
     case nsIContentPolicy::TYPE_INTERNAL_SCRIPT:
     case nsIContentPolicy::TYPE_INTERNAL_SCRIPT_PRELOAD:
+    case nsIContentPolicy::TYPE_INTERNAL_MODULE:
+    case nsIContentPolicy::TYPE_INTERNAL_MODULE_PRELOAD:
     case nsIContentPolicy::TYPE_INTERNAL_SERVICE_WORKER:
     case nsIContentPolicy::TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS:
     case nsIContentPolicy::TYPE_SCRIPT:
       destination = RequestDestination::Script;
       break;
     case nsIContentPolicy::TYPE_INTERNAL_WORKER:
       destination = RequestDestination::Worker;
       break;
--- a/dom/fetch/InternalRequest.h
+++ b/dom/fetch/InternalRequest.h
@@ -44,16 +44,17 @@ namespace dom {
  * font              | TYPE_FONT
  * image             | TYPE_INTERNAL_IMAGE, TYPE_INTERNAL_IMAGE_PRELOAD,
  *                   | TYPE_IMAGE, TYPE_INTERNAL_IMAGE_FAVICON, TYPE_IMAGESET
  * manifest          | TYPE_WEB_MANIFEST
  * object            | TYPE_INTERNAL_OBJECT, TYPE_OBJECT
  * "paintworklet"    | TODO
  * report"           | TODO
  * script            | TYPE_INTERNAL_SCRIPT, TYPE_INTERNAL_SCRIPT_PRELOAD,
+ *                   | TYPE_INTERNAL_MODULE, TYPE_INTERNAL_MODULE_PRELOAD,
  *                   | TYPE_SCRIPT,
  *                   | TYPE_INTERNAL_SERVICE_WORKER,
  *                   | TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS
  * sharedworker      | TYPE_INTERNAL_SHARED_WORKER
  * serviceworker     | The spec lists this as a valid value for the enum,
  *                   | however it is impossible to observe a request with this
  *                   | destination value.
  * style             | TYPE_INTERNAL_STYLESHEET,
--- a/dom/script/ScriptLoader.cpp
+++ b/dom/script/ScriptLoader.cpp
@@ -280,35 +280,46 @@ static bool IsScriptEventHandler(ScriptK
     // '('. Not good enough.
 
     return true;
   }
 
   return false;
 }
 
+nsContentPolicyType ScriptLoadRequestToContentPolicyType(
+    ScriptLoadRequest* aRequest) {
+  if (aRequest->IsPreload()) {
+    return aRequest->IsModuleRequest()
+               ? nsIContentPolicy::TYPE_INTERNAL_MODULE_PRELOAD
+               : nsIContentPolicy::TYPE_INTERNAL_SCRIPT_PRELOAD;
+  }
+
+  return aRequest->IsModuleRequest() ? nsIContentPolicy::TYPE_INTERNAL_MODULE
+                                     : nsIContentPolicy::TYPE_INTERNAL_SCRIPT;
+}
+
 nsresult ScriptLoader::CheckContentPolicy(Document* aDocument,
-                                          nsISupports* aContext, nsIURI* aURI,
+                                          nsISupports* aContext,
                                           const nsAString& aType,
-                                          bool aIsPreLoad) {
+                                          ScriptLoadRequest* aRequest) {
   nsContentPolicyType contentPolicyType =
-      aIsPreLoad ? nsIContentPolicy::TYPE_INTERNAL_SCRIPT_PRELOAD
-                 : nsIContentPolicy::TYPE_INTERNAL_SCRIPT;
+      ScriptLoadRequestToContentPolicyType(aRequest);
 
   nsCOMPtr<nsINode> requestingNode = do_QueryInterface(aContext);
   nsCOMPtr<nsILoadInfo> secCheckLoadInfo = new net::LoadInfo(
       aDocument->NodePrincipal(),  // loading principal
       aDocument->NodePrincipal(),  // triggering principal
       requestingNode, nsILoadInfo::SEC_ONLY_FOR_EXPLICIT_CONTENTSEC_CHECK,
       contentPolicyType);
 
   int16_t shouldLoad = nsIContentPolicy::ACCEPT;
   nsresult rv = NS_CheckContentLoadPolicy(
-      aURI, secCheckLoadInfo, NS_LossyConvertUTF16toASCII(aType), &shouldLoad,
-      nsContentUtils::GetContentPolicy());
+      aRequest->mURI, secCheckLoadInfo, NS_LossyConvertUTF16toASCII(aType),
+      &shouldLoad, nsContentUtils::GetContentPolicy());
   if (NS_FAILED(rv) || NS_CP_REJECTED(shouldLoad)) {
     if (NS_FAILED(rv) || shouldLoad != nsIContentPolicy::REJECT_TYPE) {
       return NS_ERROR_CONTENT_BLOCKED;
     }
     return NS_ERROR_CONTENT_BLOCKED_SHOW_ALT;
   }
 
   return NS_OK;
@@ -1188,18 +1199,17 @@ nsresult ScriptLoader::StartLoad(ScriptL
           ->Then(GetMainThreadSerialEventTarget(), __func__, request,
                  &ModuleLoadRequest::ModuleLoaded,
                  &ModuleLoadRequest::LoadFailed);
       return NS_OK;
     }
   }
 
   nsContentPolicyType contentPolicyType =
-      aRequest->IsPreload() ? nsIContentPolicy::TYPE_INTERNAL_SCRIPT_PRELOAD
-                            : nsIContentPolicy::TYPE_INTERNAL_SCRIPT;
+      ScriptLoadRequestToContentPolicyType(aRequest);
   nsCOMPtr<nsINode> context;
   if (aRequest->Element()) {
     context = do_QueryInterface(aRequest->Element());
   } else {
     context = mDocument;
   }
 
   nsCOMPtr<nsILoadGroup> loadGroup = mDocument->GetDocumentLoadGroup();
@@ -1502,18 +1512,18 @@ bool ScriptLoader::ProcessExternalScript
         NewRunnableMethod("nsIScriptElement::FireErrorEvent", aElement,
                           &nsIScriptElement::FireErrorEvent));
     return false;
   }
 
   RefPtr<ScriptLoadRequest> request =
       LookupPreloadRequest(aElement, aScriptKind);
 
-  if (request && NS_FAILED(CheckContentPolicy(
-                     mDocument, aElement, request->mURI, aTypeAttr, false))) {
+  if (request &&
+      NS_FAILED(CheckContentPolicy(mDocument, aElement, aTypeAttr, request))) {
     LOG(("ScriptLoader (%p): content policy check failed for preload", this));
 
     // Probably plans have changed; even though the preload was allowed seems
     // like the actual load is not; let's cancel the preload request.
     request->Cancel();
     AccumulateCategorical(LABELS_DOM_SCRIPT_PRELOAD_RESULT::RejectedByPolicy);
     return false;
   }
--- a/dom/script/ScriptLoader.h
+++ b/dom/script/ScriptLoader.h
@@ -379,18 +379,18 @@ class ScriptLoader final : public nsISup
    * requests.
    */
   mozilla::net::ReferrerPolicy GetReferrerPolicy(nsIScriptElement* aElement);
 
   /**
    * Helper function to check the content policy for a given request.
    */
   static nsresult CheckContentPolicy(Document* aDocument, nsISupports* aContext,
-                                     nsIURI* aURI, const nsAString& aType,
-                                     bool aIsPreLoad);
+                                     const nsAString& aType,
+                                     ScriptLoadRequest* aRequest);
 
   /**
    * Start a load for aRequest's URI.
    */
   nsresult StartLoad(ScriptLoadRequest* aRequest);
 
   /**
    * Abort the current stream, and re-start with a new load request from scratch
--- a/dom/security/nsCSPUtils.cpp
+++ b/dom/security/nsCSPUtils.cpp
@@ -189,16 +189,18 @@ CSPDirective CSP_ContentTypeToDirective(
     case nsIContentPolicy::TYPE_IMAGESET:
       return nsIContentSecurityPolicy::IMG_SRC_DIRECTIVE;
 
     // BLock XSLT as script, see bug 910139
     case nsIContentPolicy::TYPE_XSLT:
     case nsIContentPolicy::TYPE_SCRIPT:
     case nsIContentPolicy::TYPE_INTERNAL_SCRIPT:
     case nsIContentPolicy::TYPE_INTERNAL_SCRIPT_PRELOAD:
+    case nsIContentPolicy::TYPE_INTERNAL_MODULE:
+    case nsIContentPolicy::TYPE_INTERNAL_MODULE_PRELOAD:
     case nsIContentPolicy::TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS:
       return nsIContentSecurityPolicy::SCRIPT_SRC_DIRECTIVE;
 
     case nsIContentPolicy::TYPE_STYLESHEET:
       return nsIContentSecurityPolicy::STYLE_SRC_DIRECTIVE;
 
     case nsIContentPolicy::TYPE_FONT:
       return nsIContentSecurityPolicy::FONT_SRC_DIRECTIVE;
--- a/extensions/permissions/nsContentBlocker.cpp
+++ b/extensions/permissions/nsContentBlocker.cpp
@@ -63,16 +63,18 @@ static const char *kTypeString[] = {
     "",  // TYPE_INTERNAL_IMAGE
     "",  // TYPE_INTERNAL_IMAGE_PRELOAD
     "",  // TYPE_INTERNAL_STYLESHEET
     "",  // TYPE_INTERNAL_STYLESHEET_PRELOAD
     "",  // TYPE_INTERNAL_IMAGE_FAVICON
     "",  // TYPE_INTERNAL_WORKERS_IMPORT_SCRIPTS
     "saveas_download",
     "speculative",
+    "",  // TYPE_INTERNAL_MODULE
+    "",  // TYPE_INTERNAL_MODULE_PRELOAD
 };
 
 #define NUMBER_OF_TYPES MOZ_ARRAY_LENGTH(kTypeString)
 uint8_t nsContentBlocker::mBehaviorPref[NUMBER_OF_TYPES];
 
 NS_IMPL_ISUPPORTS(nsContentBlocker, nsIContentPolicy, nsIObserver,
                   nsISupportsWeakReference)
 
--- a/netwerk/base/nsINetworkInterceptController.idl
+++ b/netwerk/base/nsINetworkInterceptController.idl
@@ -193,16 +193,18 @@ interface nsIInterceptedChannel : nsISup
     {
       if (!nsContentUtils::IsNonSubresourceRequest(aChannel)) {
         nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo();
         if (loadInfo) {
           switch(loadInfo->InternalContentPolicyType()) {
             case nsIContentPolicy::TYPE_SCRIPT:
             case nsIContentPolicy::TYPE_INTERNAL_SCRIPT:
             case nsIContentPolicy::TYPE_INTERNAL_SCRIPT_PRELOAD:
+            case nsIContentPolicy::TYPE_INTERNAL_MODULE:
+            case nsIContentPolicy::TYPE_INTERNAL_MODULE_PRELOAD:
             case nsIContentPolicy::TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS: {
               aKey = NS_LITERAL_CSTRING("subresource-script");
               break;
             }
             case nsIContentPolicy::TYPE_IMAGE:
             case nsIContentPolicy::TYPE_INTERNAL_IMAGE:
             case nsIContentPolicy::TYPE_INTERNAL_IMAGE_PRELOAD:
             case nsIContentPolicy::TYPE_INTERNAL_IMAGE_FAVICON: {
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -1376,16 +1376,18 @@ nsresult EnsureMIMEOfScript(nsHttpChanne
         Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::javaScript);
     return NS_OK;
   }
 
   switch (aLoadInfo->InternalContentPolicyType()) {
     case nsIContentPolicy::TYPE_SCRIPT:
     case nsIContentPolicy::TYPE_INTERNAL_SCRIPT:
     case nsIContentPolicy::TYPE_INTERNAL_SCRIPT_PRELOAD:
+    case nsIContentPolicy::TYPE_INTERNAL_MODULE:
+    case nsIContentPolicy::TYPE_INTERNAL_MODULE_PRELOAD:
       AccumulateCategorical(
           Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::script_load);
       break;
     case nsIContentPolicy::TYPE_INTERNAL_WORKER:
     case nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER:
       AccumulateCategorical(
           Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::worker_load);
       break;