Bug 782654 - Add logic to check expandedPrincipal for addon content scripts.
authorTanvi Vyas <tvyas@mozilla.com>
Thu, 13 Dec 2012 14:53:06 -0800
changeset 116000 1c5601022840424fa192fc0c1bb29cd8ef980d0a
parent 115999 eef87ef1581499b68498018373a666dfe019f563
child 116001 fb6ef9590c392947d1c4e7a722269f81f0e1ae87
push id24034
push useremorley@mozilla.com
push dateFri, 14 Dec 2012 15:28:57 +0000
treeherdermozilla-central@50d8f411d305 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs782654
milestone20.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 782654 - Add logic to check expandedPrincipal for addon content scripts. (r=smaug)
content/base/src/nsMixedContentBlocker.cpp
--- a/content/base/src/nsMixedContentBlocker.cpp
+++ b/content/base/src/nsMixedContentBlocker.cpp
@@ -15,16 +15,17 @@
 #include "nsContentUtils.h"
 #include "nsNetUtil.h"
 #include "nsIRequest.h"
 #include "nsIDocument.h"
 #include "nsIContentViewer.h"
 #include "nsIChannel.h"
 #include "nsIHttpChannel.h"
 #include "mozilla/Preferences.h"
+#include "nsIScriptObjectPrincipal.h"
 
 #include "prlog.h"
 
 using namespace mozilla;
 
 // Is mixed script blocking (fonts, plugin content, scripts, stylesheets,
 // iframes, websockets, XHR) enabled?
 bool nsMixedContentBlocker::sBlockMixedScript = false;
@@ -53,39 +54,39 @@ public:
     // nsISecurityEventSink.
 
 
     // Mixed content was allowed and is about to load; get the document and
     // set the approriate flag to true if we are about to load Mixed Active
     // Content.
     nsCOMPtr<nsIDocShell> docShell = NS_CP_GetDocShellFromContext(mContext);
     nsCOMPtr<nsIDocShellTreeItem> currentDocShellTreeItem(do_QueryInterface(docShell));
-    if(!currentDocShellTreeItem) {
+    if (!currentDocShellTreeItem) {
         return NS_OK;
     }
     nsCOMPtr<nsIDocShellTreeItem> sameTypeRoot;
     currentDocShellTreeItem->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRoot));
     NS_ASSERTION(sameTypeRoot, "No document shell root tree item from document shell tree item!");
 
     // now get the document from sameTypeRoot
     nsCOMPtr<nsIDocument> rootDoc = do_GetInterface(sameTypeRoot);
     NS_ASSERTION(rootDoc, "No root document from document shell root tree item.");
 
 
-    if(mType == eMixedScript) {
+    if (mType == eMixedScript) {
       rootDoc->SetHasMixedActiveContentLoaded(true);
 
       // Update the security UI in the tab with the blocked mixed content
       nsCOMPtr<nsISecurityEventSink> eventSink = do_QueryInterface(docShell);
       if (eventSink) {
         eventSink->OnSecurityChange(mContext, nsIWebProgressListener::STATE_IS_BROKEN);
       }
 
     } else {
-        if(mType == eMixedDisplay) {
+        if (mType == eMixedDisplay) {
           //Do Nothing for now; state will already be set STATE_IS_BROKEN
         }
     }
 
 
 
     return NS_OK;
   }
@@ -262,29 +263,54 @@ nsMixedContentBlocker::ShouldLoad(uint32
     return NS_ERROR_FAILURE;
   }
 
   if (schemeLocal || schemeNoReturnData || schemeInherits || schemeSecure) {
      return NS_OK;
   }
 
   // We need aRequestingLocation to pull out the scheme. If it isn't passed
-  // in, get it from the DOM node.
+  // in, get it from the aRequestingPricipal
   if (!aRequestingLocation) {
-    nsCOMPtr<nsINode> node = do_QueryInterface(aRequestingContext);
-    if (node) {
+    if (!aRequestPrincipal) {
+      // If we don't have aRequestPrincipal, try getting it from the
+      // DOM node using aRequestingContext
+      nsCOMPtr<nsINode> node = do_QueryInterface(aRequestingContext);
+      if (node) {
+        aRequestPrincipal = node->NodePrincipal();
+      } else {
+        // Try using the window's script object principal if it's not a node.
+        nsCOMPtr<nsIScriptObjectPrincipal> scriptObjPrin = do_QueryInterface(aRequestingContext);
+        if (scriptObjPrin) {
+          aRequestPrincipal = scriptObjPrin->GetPrincipal();
+        }
+      }
+    }
+    if (aRequestPrincipal) {
       nsCOMPtr<nsIURI> principalUri;
-      node->NodePrincipal()->GetURI(getter_AddRefs(principalUri));
-      aRequestingLocation = principalUri;
+      nsresult rvalue = aRequestPrincipal->GetURI(getter_AddRefs(principalUri));
+      if (NS_SUCCEEDED(rvalue)) {
+        aRequestingLocation = principalUri;
+      }
     }
-    // If we still don't have a requesting location then we can't tell if
-    // this is a mixed content load.  Deny to be safe.
+
     if (!aRequestingLocation) {
-      *aDecision = REJECT_REQUEST;
-      return NS_OK;
+      // If content scripts from an addon are causing this load, they have an
+      // ExpandedPrincipal instead of a Principal. This is pseudo-privileged code, so allow
+      // the load. Or if this is system principal, allow the load.
+      nsCOMPtr<nsIExpandedPrincipal> expanded = do_QueryInterface(aRequestPrincipal);
+      if (expanded || (aRequestPrincipal && nsContentUtils::IsSystemPrincipal(aRequestPrincipal))) {
+        *aDecision = ACCEPT;
+        return NS_OK;
+      } else {
+        // We still don't have a requesting location and there is no Expanded Principal.
+        // We can't tell if this is a mixed content load.  Deny to be safe.
+        *aDecision = REJECT_REQUEST;
+        return NS_OK;
+      }
     }
   }
 
   // Check the parent scheme. If it is not an HTTPS page then mixed content
   // restrictions do not apply.
   bool parentIsHttps;
   nsresult rv = aRequestingLocation->SchemeIs("https", &parentIsHttps);
   if (NS_FAILED(rv)) {