Bug 803225 - Mixed Content Blocker - Check for other secure schemes, in additon to https. r=bz
☠☠ backed out by 6d4a9a61a335 ☠ ☠
authorTanvi Vyas <tvyas@mozilla.com>
Thu, 15 Nov 2012 20:34:56 -0500
changeset 113450 df27137cb7d1a4cb060b72bffed8ffd35212ce0f
parent 113449 cc2469a8b41ad3d3472f3cd691e25c4d9f50558b
child 113451 5bdf8bbcd02f481ea04fef10e255142b0c202ec1
push id23872
push useremorley@mozilla.com
push dateFri, 16 Nov 2012 17:06:27 +0000
treeherdermozilla-central@a7ed19f7d21a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs803225
milestone19.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 803225 - Mixed Content Blocker - Check for other secure schemes, in additon to https. r=bz
content/base/src/nsMixedContentBlocker.cpp
netwerk/base/public/nsIProtocolHandler.idl
netwerk/protocol/about/nsAboutProtocolHandler.cpp
netwerk/protocol/http/nsHttpHandler.cpp
--- a/content/base/src/nsMixedContentBlocker.cpp
+++ b/content/base/src/nsMixedContentBlocker.cpp
@@ -7,16 +7,17 @@
 #include "nsContentPolicyUtils.h"
 
 #include "nsINode.h"
 #include "nsCOMPtr.h"
 #include "nsIDocShell.h"
 #include "nsISecurityEventSink.h"
 #include "nsIWebProgressListener.h"
 #include "nsContentUtils.h"
+#include "nsNetUtil.h"
 #include "mozilla/Preferences.h"
 
 using namespace mozilla;
 
 // Is mixed script blocking (fonts, plugin content, scripts, stylesheets,
 // iframes, websockets, XHR) enabled?
 bool nsMixedContentBlocker::sBlockMixedScript = false;
 
@@ -48,17 +49,17 @@ public:
 
     return NS_OK;
   }
 private:
   // The requesting context for the content load. Generally, a DOM node from
   // the document that caused the load.
   nsCOMPtr<nsISupports> mContext;
 
-  // The type of mixed content that was blocked, i.e. active or display
+  // The type of mixed content that was blocked, e.g. active or display
   unsigned short mType;
 };
 */
 
 nsMixedContentBlocker::nsMixedContentBlocker()
 {
   // Cache the pref for mixed script blocking
   Preferences::AddBoolVarCache(&sBlockMixedScript,
@@ -89,18 +90,19 @@ nsMixedContentBlocker::ShouldLoad(uint32
   *aDecision = nsIContentPolicy::ACCEPT;
 
   // If mixed script blocking and mixed display blocking are turned off
   // we can return early
   if (!sBlockMixedScript && !sBlockMixedDisplay) {
     return NS_OK;
   }
 
-  // Top-level load cannot be mixed content so allow it
-  if (aContentType == nsIContentPolicy::TYPE_DOCUMENT) {
+  // Top-level load cannot be mixed content so allow it.
+  // Creating insecure websocket connections in a secure page is blocked already in websocket constructor.
+  if (aContentType == nsIContentPolicy::TYPE_DOCUMENT || aContentType == nsIContentPolicy::TYPE_WEBSOCKET) {
     return NS_OK;
   }
 
   // We need aRequestingLocation to pull out the scheme. If it isn't passed
   // in, get it from the DOM node.
   if (!aRequestingLocation) {
     nsCOMPtr<nsINode> node = do_QueryInterface(aRequestingContext);
     if (node) {
@@ -119,21 +121,46 @@ nsMixedContentBlocker::ShouldLoad(uint32
   // Check the parent scheme. If it is not an HTTPS page then mixed content
   // restrictions do not apply.
   bool parentIsHttps;
   if (NS_FAILED(aRequestingLocation->SchemeIs("https", &parentIsHttps)) ||
       !parentIsHttps) {
     return NS_OK;
   }
 
-  // Get the scheme of the sub-document resource to be requested. If it is
-  // an HTTPS load then mixed content doesn't apply.
-  bool isHttps;
-  if (NS_FAILED(aContentLocation->SchemeIs("https", &isHttps)) || isHttps) {
-    return NS_OK;
+ /* Get the scheme of the sub-document resource to be requested. If it is
+  * a safe to load in an https context then mixed content doesn't apply.
+  *
+  * Check Protocol Flags to determine if scheme is safe to load:
+  * URI_DOES_NOT_RETURN_DATA - e.g.
+  *   "mailto"
+  * URI_IS_LOCAL_RESOURCE - e.g.
+  *   "data",
+  *   "resource",
+  *   "moz-icon"
+  * URI_INHERITS_SECURITY_CONTEXT - e.g.
+  *   "javascript"
+  * URI_SAFE_TO_LOAD_IN_SECURE_CONTEXT - e.g.
+  *   "https",
+  *   "moz-safe-about"
+  *
+  */
+  bool schemeLocal = false;
+  bool schemeNoReturnData = false;
+  bool schemeInherits = false;
+  bool schemeSecure = false;
+  if (NS_FAILED(NS_URIChainHasFlags(aContentLocation, nsIProtocolHandler::URI_IS_LOCAL_RESOURCE , &schemeLocal))  ||
+      NS_FAILED(NS_URIChainHasFlags(aContentLocation, nsIProtocolHandler::URI_DOES_NOT_RETURN_DATA, &schemeNoReturnData)) ||
+      NS_FAILED(NS_URIChainHasFlags(aContentLocation, nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT, &schemeInherits)) ||
+      NS_FAILED(NS_URIChainHasFlags(aContentLocation, nsIProtocolHandler::URI_SAFE_TO_LOAD_IN_SECURE_CONTEXT, &schemeSecure))) {
+    return NS_ERROR_FAILURE;
+  }
+
+  if (schemeLocal || schemeNoReturnData || schemeInherits || schemeSecure) {
+     return NS_OK;
   }
 
   // If we are here we have mixed content.
 
   // Decide whether or not to allow the mixed content based on what type of
   // content it is and if the user permitted it.
   switch (aContentType) {
     case nsIContentPolicy::TYPE_FONT:
@@ -190,19 +217,19 @@ nsMixedContentBlocker::ShouldProcess(uin
                                      nsIURI* aContentLocation,
                                      nsIURI* aRequestingLocation,
                                      nsISupports* aRequestingContext,
                                      const nsACString& aMimeGuess,
                                      nsISupports* aExtra,
                                      nsIPrincipal* aRequestPrincipal,
                                      int16_t* aDecision)
 {
-  if(!aContentLocation) {
+  if (!aContentLocation) {
     // aContentLocation may be null when a plugin is loading without an associated URI resource
-    if(aContentType == TYPE_OBJECT) {
+    if (aContentType == TYPE_OBJECT) {
        return NS_OK;
     } else {
        return NS_ERROR_FAILURE;
     }
   }
 
   return ShouldLoad(aContentType, aContentLocation, aRequestingLocation,
                     aRequestingContext, aMimeGuess, aExtra, aRequestPrincipal,
--- a/netwerk/base/public/nsIProtocolHandler.idl
+++ b/netwerk/base/public/nsIProtocolHandler.idl
@@ -241,16 +241,23 @@ interface nsIProtocolHandler : nsISuppor
     const unsigned long URI_CROSS_ORIGIN_NEEDS_WEBAPPS_PERM = (1<<16);
 
     /**
      * Channels for this protocol don't need to spin the event loop to handle
      * Open() and reads on the resulting stream.
      */
     const unsigned long URI_SYNC_LOAD_IS_OK = (1<<17);
 
+    /**
+     * URI is secure to load in an https page and should not be blocked
+     * by nsMixedContentBlocker
+     */
+    const unsigned long URI_SAFE_TO_LOAD_IN_SECURE_CONTEXT = (1<<18);
+
+
 };
 
 %{C++
 /**
  * Protocol handlers are registered with XPCOM under the following CONTRACTID prefix:
  */
 #define NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "@mozilla.org/network/protocol;1?name="
 /**
--- a/netwerk/protocol/about/nsAboutProtocolHandler.cpp
+++ b/netwerk/protocol/about/nsAboutProtocolHandler.cpp
@@ -187,17 +187,17 @@ nsSafeAboutProtocolHandler::GetDefaultPo
 {
     *result = -1;        // no port for moz-safe-about: URLs
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSafeAboutProtocolHandler::GetProtocolFlags(uint32_t *result)
 {
-    *result = URI_NORELATIVE | URI_NOAUTH | URI_LOADABLE_BY_ANYONE;
+    *result = URI_NORELATIVE | URI_NOAUTH | URI_LOADABLE_BY_ANYONE | URI_SAFE_TO_LOAD_IN_SECURE_CONTEXT;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSafeAboutProtocolHandler::NewURI(const nsACString &aSpec,
                                    const char *aCharset, // ignore charset info
                                    nsIURI *aBaseURI,
                                    nsIURI **result)
--- a/netwerk/protocol/http/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/nsHttpHandler.cpp
@@ -1699,17 +1699,17 @@ nsHttpsHandler::GetDefaultPort(int32_t *
 {
     *aPort = NS_HTTPS_DEFAULT_PORT;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHttpsHandler::GetProtocolFlags(uint32_t *aProtocolFlags)
 {
-    *aProtocolFlags = NS_HTTP_PROTOCOL_FLAGS;
+    *aProtocolFlags = NS_HTTP_PROTOCOL_FLAGS | URI_SAFE_TO_LOAD_IN_SECURE_CONTEXT;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHttpsHandler::NewURI(const nsACString &aSpec,
                        const char *aOriginCharset,
                        nsIURI *aBaseURI,
                        nsIURI **_retval)