Bug 1221365 - Move "Is origin potentially trustworthy?" logic outside ServiceWorkerManager.cpp. r=ckerschb, r=bkelly, a=ritu
authorMatthew Noorenberghe <mozilla@noorenberghe.ca>
Fri, 06 Nov 2015 11:10:17 -0800
changeset 305475 9814dd56b94ff808c2a036bbad902f16eba944c1
parent 305474 77e2c8fab108b4804defcc5816e93815ed6cf41b
child 305476 d35eb3ac914be5e51e8b336cecb06eca5d90144c
push id1001
push userraliiev@mozilla.com
push dateMon, 18 Jan 2016 19:06:03 +0000
treeherdermozilla-release@8b89261f3ac4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersckerschb, bkelly, ritu
bugs1221365
milestone44.0a2
Bug 1221365 - Move "Is origin potentially trustworthy?" logic outside ServiceWorkerManager.cpp. r=ckerschb, r=bkelly, a=ritu
dom/interfaces/security/nsIContentSecurityManager.idl
dom/media/MediaManager.cpp
dom/security/nsContentSecurityManager.cpp
dom/workers/ServiceWorkerManager.cpp
--- a/dom/interfaces/security/nsIContentSecurityManager.idl
+++ b/dom/interfaces/security/nsIContentSecurityManager.idl
@@ -1,24 +1,24 @@
 /* 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 "nsISupports.idl"
 
 interface nsIChannel;
 interface nsIStreamListener;
+interface nsIURI;
 
 /**
  * nsIContentSecurityManager
- * Describes an XPCOM component used to perform security checks
- * right before opnening a channel.
+ * Describes an XPCOM component used to perform security checks.
  */
 
-[scriptable, uuid(70eaa956-1077-41f6-bef8-d722cea31245)]
+[scriptable, uuid(ec955006-747d-4151-aeec-70bd0edc3341)]
 interface nsIContentSecurityManager : nsISupports
 {
   /**
    * Checks whether a channel is allowed to access the given URI and
    * whether the channel should be openend or should be blocked consulting
    * internal security checks like Same Origin Policy, Content Security
    * Policy, Mixed Content Blocker, etc.
    *
@@ -35,9 +35,20 @@ interface nsIContentSecurityManager : ns
    *
    * @throws NS_ERROR_DOM_BAD_URI
    *     If accessing the URI is not allowed (e.g. prohibted by SOP)
    * @throws NS_ERROR_CONTENT_BLOCKED
    *     If any of the security policies (CSP, Mixed content) is violated
    */
    nsIStreamListener performSecurityCheck(in nsIChannel aChannel,
                                           in nsIStreamListener aStreamListener);
+
+  /**
+   * Implementation of
+   * https://w3c.github.io/webappsec-secure-contexts/#is-origin-trustworthy
+   *
+   * This method should only be used when the context of the URI isn't available
+   * since isSecureContext is preffered as it handles parent contexts.
+   *
+   * This method returns false instead of throwing upon errors.
+   */
+  boolean isURIPotentiallyTrustworthy(in nsIURI aURI);
 };
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -1816,17 +1816,17 @@ MediaManager::GetUserMedia(nsPIDOMWindow
   nsCString host;
   nsresult rv = docURI->GetHost(host);
   // Test for some other schemes that ServiceWorker recognizes
   bool isFile;
   docURI->SchemeIs("file", &isFile);
   bool isApp;
   docURI->SchemeIs("app", &isApp);
   // Same localhost check as ServiceWorkers uses
-  // (see IsFromAuthenticatedOriginInternal())
+  // (see IsURIPotentiallyTrustworthy())
   bool isLocalhost = NS_SUCCEEDED(rv) &&
                      (host.LowerCaseEqualsLiteral("localhost") ||
                       host.LowerCaseEqualsLiteral("127.0.0.1") ||
                       host.LowerCaseEqualsLiteral("::1"));
 
   // Record telemetry about whether the source of the call was secure, i.e.,
   // privileged or HTTPS.  We may handle other cases
   if (loop) {
--- a/dom/security/nsContentSecurityManager.cpp
+++ b/dom/security/nsContentSecurityManager.cpp
@@ -400,8 +400,41 @@ nsContentSecurityManager::PerformSecurit
 {
   nsCOMPtr<nsIStreamListener> inAndOutListener = aStreamListener;
   nsresult rv = doContentSecurityCheck(aChannel, inAndOutListener);
   NS_ENSURE_SUCCESS(rv, rv);
 
   inAndOutListener.forget(outStreamListener);
   return NS_OK;
 }
+
+NS_IMETHODIMP
+nsContentSecurityManager::IsURIPotentiallyTrustworthy(nsIURI* aURI, bool* aIsTrustWorthy)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  NS_ENSURE_ARG_POINTER(aURI);
+  NS_ENSURE_ARG_POINTER(aIsTrustWorthy);
+
+  *aIsTrustWorthy = false;
+  nsAutoCString scheme;
+  nsresult rv = aURI->GetScheme(scheme);
+  NS_ENSURE_SUCCESS(rv, NS_OK);
+
+  if (scheme.EqualsLiteral("https") ||
+      scheme.EqualsLiteral("file") ||
+      scheme.EqualsLiteral("app")) {
+    *aIsTrustWorthy = true;
+    return NS_OK;
+  }
+
+  nsAutoCString host;
+  rv = aURI->GetHost(host);
+  NS_ENSURE_SUCCESS(rv, NS_OK);
+
+  if (host.Equals("127.0.0.1") ||
+      host.Equals("localhost") ||
+      host.Equals("::1")) {
+    *aIsTrustWorthy = true;
+    return NS_OK;
+  }
+
+  return NS_OK;
+}
--- a/dom/workers/ServiceWorkerManager.cpp
+++ b/dom/workers/ServiceWorkerManager.cpp
@@ -45,16 +45,17 @@
 #include "mozilla/dom/RootedDictionary.h"
 #include "mozilla/ipc/BackgroundChild.h"
 #include "mozilla/ipc/PBackgroundChild.h"
 #include "mozilla/ipc/PBackgroundSharedTypes.h"
 #include "mozilla/unused.h"
 #include "mozilla/EnumSet.h"
 
 #include "nsContentPolicyUtils.h"
+#include "nsContentSecurityManager.h"
 #include "nsContentUtils.h"
 #include "nsGlobalWindow.h"
 #include "nsNetUtil.h"
 #include "nsIURL.h"
 #include "nsProxyRelease.h"
 #include "nsQueryObject.h"
 #include "nsTArray.h"
 
@@ -1327,80 +1328,32 @@ ContinueUpdateRunnable::Run()
 void
 ContinueInstallTask::ContinueAfterWorkerEvent(bool aSuccess)
 {
   // This does not start the job immediately if there are other jobs in the
   // queue, which captures the "atomic" behaviour we want.
   mJob->ContinueAfterInstallEvent(aSuccess);
 }
 
-static bool
-IsFromAuthenticatedOriginInternal(nsIDocument* aDoc)
-{
-  nsCOMPtr<nsIURI> documentURI = aDoc->GetDocumentURI();
-
-  bool authenticatedOrigin = false;
-  nsresult rv;
-  if (!authenticatedOrigin) {
-    nsAutoCString scheme;
-    rv = documentURI->GetScheme(scheme);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return false;
-    }
-
-    if (scheme.EqualsLiteral("https") ||
-        scheme.EqualsLiteral("file") ||
-        scheme.EqualsLiteral("app")) {
-      authenticatedOrigin = true;
-    }
-  }
-
-  if (!authenticatedOrigin) {
-    nsAutoCString host;
-    rv = documentURI->GetHost(host);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return false;
-    }
-
-    if (host.Equals("127.0.0.1") ||
-        host.Equals("localhost") ||
-        host.Equals("::1")) {
-      authenticatedOrigin = true;
-    }
-  }
-
-  if (!authenticatedOrigin) {
-    bool isFile;
-    rv = documentURI->SchemeIs("file", &isFile);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return false;
-    }
-
-    if (!isFile) {
-      bool isHttps;
-      rv = documentURI->SchemeIs("https", &isHttps);
-      if (NS_WARN_IF(NS_FAILED(rv))) {
-        return false;
-      }
-      authenticatedOrigin = isHttps;
-    }
-  }
-
-  return authenticatedOrigin;
-}
-
 // This function implements parts of the step 3 of the following algorithm:
 // https://w3c.github.io/webappsec/specs/powerfulfeatures/#settings-secure
 static bool
 IsFromAuthenticatedOrigin(nsIDocument* aDoc)
 {
   MOZ_ASSERT(aDoc);
   nsCOMPtr<nsIDocument> doc(aDoc);
+  nsCOMPtr<nsIContentSecurityManager> csm = do_GetService(NS_CONTENTSECURITYMANAGER_CONTRACTID);
+  if (NS_WARN_IF(!csm)) {
+    return false;
+  }
+
   while (doc && !nsContentUtils::IsChromeDoc(doc)) {
-    if (!IsFromAuthenticatedOriginInternal(doc)) {
+    bool trustworthyURI = false;
+    csm->IsURIPotentiallyTrustworthy(doc->GetDocumentURI(), &trustworthyURI);
+    if (!trustworthyURI) {
       return false;
     }
 
     doc = doc->GetParentDocument();
   }
   return true;
 }