Bug840388 - Check if a iframe has any https parents. If not, then there is no mixed content since we are not on a secure page. r=smaug a=bbajaj
authorTanvi Vyas <tvyas@mozilla.com>
Fri, 29 Mar 2013 17:58:31 -0700
changeset 128732 c4237eb085c3e74fe41b837c84df46623697c857
parent 128731 66301943ef8401dc2ed7453a9833530e645feb9c
child 128733 4717c038bc0c1f3436ccc4c8648e7986959a590e
push id3574
push usertvyas@mozilla.com
push dateSat, 30 Mar 2013 01:00:08 +0000
treeherdermozilla-aurora@3274a156c130 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug, bbajaj
bugs840388
milestone21.0a2
Bug840388 - Check if a iframe has any https parents. If not, then there is no mixed content since we are not on a secure page. r=smaug a=bbajaj
content/base/src/nsMixedContentBlocker.cpp
--- a/content/base/src/nsMixedContentBlocker.cpp
+++ b/content/base/src/nsMixedContentBlocker.cpp
@@ -17,16 +17,17 @@
 #include "nsIDocument.h"
 #include "nsIContentViewer.h"
 #include "nsIChannel.h"
 #include "nsIHttpChannel.h"
 #include "mozilla/Preferences.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsISecureBrowserUI.h"
 #include "nsIDocumentLoader.h"
+#include "nsIWebNavigation.h"
 #include "nsLoadGroup.h"
 
 #include "prlog.h"
 
 using namespace mozilla;
 
 // Is mixed script blocking (fonts, plugin content, scripts, stylesheets,
 // iframes, websockets, XHR) enabled?
@@ -347,33 +348,74 @@ nsMixedContentBlocker::ShouldLoad(uint32
     *aDecision = REJECT_REQUEST;
     return NS_OK;
   }
   if (!parentIsHttps) {
     *aDecision = ACCEPT;
     return NS_OK;
   }
 
-  // If we are here we have mixed content.
-
   // Determine if the rootDoc is https and if the user decided to allow Mixed Content
   nsCOMPtr<nsIDocShell> docShell = NS_CP_GetDocShellFromContext(aRequestingContext);
   NS_ENSURE_TRUE(docShell, NS_OK);
   bool rootHasSecureConnection = false;
   bool allowMixedContent = false;
   bool isRootDocShell = false;
   rv = docShell->GetAllowMixedContentAndConnectionData(&rootHasSecureConnection, &allowMixedContent, &isRootDocShell);
   if (NS_FAILED(rv)) {
      return rv;
   }
 
-  // Get the root document from the docshell
+
+  // Get the sameTypeRoot tree item from the docshell
   nsCOMPtr<nsIDocShellTreeItem> sameTypeRoot;
   docShell->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRoot));
-  NS_ASSERTION(sameTypeRoot, "No document shell root tree item from document shell tree item!");
+  NS_ASSERTION(sameTypeRoot, "No root tree item from docshell!");
+
+  // When navigating an iframe, the iframe may be https
+  // but its parents may not be.  Check the parents to see if any of them are https.
+  // If none of the parents are https, allow the load.
+  if (aContentType == TYPE_SUBDOCUMENT && !rootHasSecureConnection) {
+
+    bool httpsParentExists = false;
+
+    nsCOMPtr<nsIDocShellTreeItem> parentTreeItem;
+    parentTreeItem = docShell;
+
+    while(!httpsParentExists && parentTreeItem) {
+      nsCOMPtr<nsIWebNavigation> parentAsNav(do_QueryInterface(parentTreeItem));
+      NS_ASSERTION(parentAsNav, "No web navigation object from parent's docshell tree item");
+      nsCOMPtr<nsIURI> parentURI;
+
+      parentAsNav->GetCurrentURI(getter_AddRefs(parentURI));
+      if (!parentURI || NS_FAILED(parentURI->SchemeIs("https", &httpsParentExists))) {
+        // if getting the URI or the scheme fails, assume there is a https parent and break.
+        httpsParentExists = true;
+        break;
+      }
+
+      // When the parent and the root are the same, we have traversed all the way up
+      // the same type docshell tree.  Break out of the while loop.
+      if(sameTypeRoot == parentTreeItem) {
+        break;
+      }
+
+      // update the parent to the grandparent.
+      nsCOMPtr<nsIDocShellTreeItem> newParentTreeItem;
+      parentTreeItem->GetSameTypeParent(getter_AddRefs(newParentTreeItem));
+      parentTreeItem = newParentTreeItem;
+    } // end while loop.
+
+    if (!httpsParentExists) {
+      *aDecision = nsIContentPolicy::ACCEPT;
+      return NS_OK;
+    }
+  }
+
+  // Get the root document from the sameTypeRoot
   nsCOMPtr<nsIDocument> rootDoc = do_GetInterface(sameTypeRoot);
   NS_ASSERTION(rootDoc, "No root document from document shell root tree item.");
 
   // Get eventSink and the current security state from the docShell
   nsCOMPtr<nsISecurityEventSink> eventSink = do_QueryInterface(docShell);
   NS_ASSERTION(eventSink, "No eventSink from docShell.");
   nsCOMPtr<nsIDocShell> rootShell = do_GetInterface(sameTypeRoot);
   NS_ASSERTION(rootShell, "No root docshell from document shell root tree item.");