Bug 1429127 - Workers should allow the loading of file URLs if they are on the same directory of the loader, r=smaug
authorAndrea Marchesini <amarchesini@mozilla.com>
Thu, 03 May 2018 17:42:58 +0200
changeset 472951 42121539d5f4937e6ac400d5a819102341227f72
parent 472950 58fb973a0dad830e17a649c853e0cf1db5f23e92
child 472952 b3c1b37dddc22249d1cf844b92ec142095820827
push id1728
push userjlund@mozilla.com
push dateMon, 18 Jun 2018 21:12:27 +0000
treeherdermozilla-release@c296fde26f5f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1429127
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 1429127 - Workers should allow the loading of file URLs if they are on the same directory of the loader, r=smaug
dom/workers/ScriptLoader.cpp
dom/workers/WorkerLoadInfo.cpp
dom/workers/moz.build
--- a/dom/workers/ScriptLoader.cpp
+++ b/dom/workers/ScriptLoader.cpp
@@ -10,16 +10,17 @@
 #include "nsIContentPolicy.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsIDocShell.h"
 #include "nsIDOMDocument.h"
 #include "nsIHttpChannel.h"
 #include "nsIHttpChannelInternal.h"
 #include "nsIInputStreamPump.h"
 #include "nsIIOService.h"
+#include "nsIOService.h"
 #include "nsIProtocolHandler.h"
 #include "nsIScriptError.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIStreamLoader.h"
 #include "nsIStreamListenerTee.h"
 #include "nsIThreadRetargetableRequest.h"
 #include "nsIURI.h"
 
@@ -149,16 +150,28 @@ ChannelFromScriptURL(nsIPrincipal* princ
   if (parentDoc && parentDoc->NodePrincipal() != principal) {
     parentDoc = nullptr;
   }
 
   aLoadFlags |= nsIChannel::LOAD_CLASSIFY_URI;
   uint32_t secFlags = aIsMainScript ? nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED
                                     : nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS;
 
+  bool inheritAttrs = nsContentUtils::ChannelShouldInheritPrincipal(
+    principal, uri, true /* aInheritForAboutBlank */, false /* aForceInherit */);
+
+  bool isData = false;
+  rv = uri->SchemeIs("data", &isData);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  bool isURIUniqueOrigin = nsIOService::IsDataURIUniqueOpaqueOrigin() && isData;
+  if (inheritAttrs && !isURIUniqueOrigin) {
+    secFlags |= nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL;
+  }
+
   if (aWorkerScriptType == DebuggerScript) {
     // A DebuggerScript needs to be a local resource like chrome: or resource:
     bool isUIResource = false;
     rv = NS_URIChainHasFlags(uri, nsIProtocolHandler::URI_IS_UI_RESOURCE,
                              &isUIResource);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
@@ -167,18 +180,17 @@ ChannelFromScriptURL(nsIPrincipal* princ
       return NS_ERROR_DOM_SECURITY_ERR;
     }
 
     secFlags |= nsILoadInfo::SEC_ALLOW_CHROME;
   }
 
   // Note: this is for backwards compatibility and goes against spec.
   // We should find a better solution.
-  bool isData = false;
-  if (aIsMainScript && NS_SUCCEEDED(uri->SchemeIs("data", &isData)) && isData) {
+  if (aIsMainScript && isData) {
     secFlags = nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL;
   }
 
   nsContentPolicyType contentPolicyType =
     aIsMainScript ? aMainScriptContentPolicyType
                   : nsIContentPolicy::TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS;
 
   // The main service worker script should never be loaded over the network
--- a/dom/workers/WorkerLoadInfo.cpp
+++ b/dom/workers/WorkerLoadInfo.cpp
@@ -11,16 +11,17 @@
 #include "mozilla/ipc/BackgroundUtils.h"
 #include "mozilla/ipc/PBackgroundSharedTypes.h"
 #include "mozilla/LoadContext.h"
 #include "nsContentUtils.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsINetworkInterceptController.h"
 #include "nsIProtocolHandler.h"
 #include "nsITabChild.h"
+#include "nsScriptSecurityManager.h"
 #include "nsNetUtil.h"
 
 namespace mozilla {
 
 using namespace ipc;
 
 namespace dom {
 
@@ -374,21 +375,30 @@ WorkerLoadInfo::PrincipalURIMatchesScrip
     return true;
   }
 
   nsCOMPtr<nsIURI> principalURI;
   rv = mPrincipal->GetURI(getter_AddRefs(principalURI));
   NS_ENSURE_SUCCESS(rv, false);
   NS_ENSURE_TRUE(principalURI, false);
 
-  bool equal = false;
-  rv = principalURI->Equals(mBaseURI, &equal);
-  NS_ENSURE_SUCCESS(rv, false);
+  if (nsScriptSecurityManager::SecurityCompareURIs(mBaseURI, principalURI)) {
+    return true;
+  }
 
-  return equal;
+  // If strict file origin policy is in effect, local files will always fail
+  // SecurityCompareURIs unless they are identical. Explicitly check file origin
+  // policy, in that case.
+  if (nsScriptSecurityManager::GetStrictFileOriginPolicy() &&
+      NS_URIIsLocalFile(mBaseURI) &&
+      NS_RelaxStrictFileOriginPolicy(mBaseURI, principalURI)) {
+    return true;
+  }
+
+  return false;
 }
 #endif // MOZ_DIAGNOSTIC_ASSERT_ENABLED
 
 bool
 WorkerLoadInfo::ProxyReleaseMainThreadObjects(WorkerPrivate* aWorkerPrivate)
 {
   nsCOMPtr<nsILoadGroup> nullLoadGroup;
   return ProxyReleaseMainThreadObjects(aWorkerPrivate, nullLoadGroup);
--- a/dom/workers/moz.build
+++ b/dom/workers/moz.build
@@ -62,21 +62,22 @@ UNIFIED_SOURCES += [
     'WorkerPrivate.cpp',
     'WorkerRef.cpp',
     'WorkerRunnable.cpp',
     'WorkerScope.cpp',
     'WorkerThread.cpp',
 ]
 
 LOCAL_INCLUDES += [
-    '../base',
-    '../system',
+    '/caps',
     '/dom/base',
     '/dom/bindings',
+    '/dom/system',
     '/js/xpconnect/loader',
+    '/netwerk/base',
     '/xpcom/build',
     '/xpcom/threads',
 ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'