Bug 1308951 - Add a pref to whitelist specific domains as SecureContexts r=jcj r=ckerschb draft
authorRichard Barnes <rbarnes@mozilla.com>
Mon, 10 Oct 2016 11:32:24 -0400
changeset 423277 1bfc30a5c845d26dff08eb54da21cead8b9d0c9f
parent 423237 8c51fc68856eb92c2fac40cac5292f4563d8d7e7
child 533415 8925247ebd827d58cde204fc5aeefce1dc8c2975
push id31861
push userrlb@ipv.sx
push dateMon, 10 Oct 2016 19:50:16 +0000
reviewersjcj, ckerschb
bugs1308951
milestone52.0a1
Bug 1308951 - Add a pref to whitelist specific domains as SecureContexts r=jcj r=ckerschb MozReview-Commit-ID: AxihCLsBNRw
dom/security/nsContentSecurityManager.cpp
dom/security/test/unit/test_isOriginPotentiallyTrustworthy.js
--- a/dom/security/nsContentSecurityManager.cpp
+++ b/dom/security/nsContentSecurityManager.cpp
@@ -164,17 +164,17 @@ DoCORSChecks(nsIChannel* aChannel, nsILo
 }
 
 static nsresult
 DoContentSecurityChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo)
 {
   nsCOMPtr<nsIURI> uri;
   nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
   NS_ENSURE_SUCCESS(rv, rv);
-  
+
   nsContentPolicyType contentPolicyType =
     aLoadInfo->GetExternalContentPolicyType();
   nsContentPolicyType internalContentPolicyType =
     aLoadInfo->InternalContentPolicyType();
   nsCString mimeTypeGuess;
   nsCOMPtr<nsINode> requestingContext = nullptr;
 
 #ifdef DEBUG
@@ -666,10 +666,29 @@ nsContentSecurityManager::IsOriginPotent
   }
 
   if (host.Equals("127.0.0.1") ||
       host.Equals("localhost") ||
       host.Equals("::1")) {
     *aIsTrustWorthy = true;
     return NS_OK;
   }
+
+  // If a host is not considered secure according to the default algorithm, then
+  // check to see if it has been whitelisted by the user.  We only apply this
+  // whitelist for network resources, i.e., those with scheme "http" or "ws".
+  // The pref should contain a comma-separated list of hostnames.
+  if (scheme.EqualsLiteral("http") || scheme.EqualsLiteral("ws")) {
+    nsAdoptingCString whitelist = Preferences::GetCString("dom.securecontext.whitelist");
+    if (whitelist) {
+      nsCCharSeparatedTokenizer tokenizer(whitelist, ',');
+      while (tokenizer.hasMoreTokens()) {
+        const nsCSubstring& allowedHost = tokenizer.nextToken();
+        if (host.Equals(allowedHost)) {
+          *aIsTrustWorthy = true;
+          return NS_OK;
+        }
+      }
+    }
+  }
+
   return NS_OK;
 }
--- a/dom/security/test/unit/test_isOriginPotentiallyTrustworthy.js
+++ b/dom/security/test/unit/test_isOriginPotentiallyTrustworthy.js
@@ -14,26 +14,34 @@ Cu.import("resource://gre/modules/XPCOMU
 XPCOMUtils.defineLazyServiceGetter(this, "gScriptSecurityManager",
                                    "@mozilla.org/scriptsecuritymanager;1",
                                    "nsIScriptSecurityManager");
 
 XPCOMUtils.defineLazyServiceGetter(this, "gContentSecurityManager",
                                    "@mozilla.org/contentsecuritymanager;1",
                                    "nsIContentSecurityManager");
 
+var prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
+prefs.setCharPref("dom.securecontext.whitelist", "example.net,example.org");
+
 add_task(function* test_isOriginPotentiallyTrustworthy() {
   for (let [uriSpec, expectedResult] of [
     ["http://example.com/", false],
     ["https://example.com/", true],
     ["http://localhost/", true],
     ["http://127.0.0.1/", true],
     ["file:///", true],
     ["resource:///", true],
+    ["app://", true],
     ["moz-extension://", true],
+    ["wss://example.com/", true],
     ["about:config", false],
     ["urn:generic", false],
+    ["http://example.net/", true],
+    ["ws://example.org/", true],
+    ["chrome://example.net/content/messenger.xul", false],
   ]) {
     let uri = NetUtil.newURI(uriSpec);
     let principal = gScriptSecurityManager.getCodebasePrincipal(uri);
     Assert.equal(gContentSecurityManager.isOriginPotentiallyTrustworthy(principal),
                  expectedResult);
   }
 });