Bug 1309310, r=bz
authorGijs Kruitbosch <gijskruitbosch@gmail.com>
Wed, 09 Nov 2016 18:25:11 +0000
changeset 367247 fb5ae665310e4f60464ccd43b2626fdfc2087a67
parent 367246 d728a7fdade20d7fbfd8c18e46974abd7fd150e6
child 367248 3f1ec7d616d64068b447ede8d6fe2d59d2cf09b2
push id1369
push userjlorenzo@mozilla.com
push dateMon, 27 Feb 2017 14:59:41 +0000
treeherdermozilla-release@d75a1dba431f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1309310
milestone52.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 1309310, r=bz MozReview-Commit-ID: KLaMv6zfxR8
caps/nsScriptSecurityManager.cpp
netwerk/base/nsIProtocolHandler.idl
netwerk/protocol/about/nsAboutProtocolHandler.cpp
--- a/caps/nsScriptSecurityManager.cpp
+++ b/caps/nsScriptSecurityManager.cpp
@@ -798,25 +798,37 @@ nsScriptSecurityManager::CheckLoadURIWit
         // exception for foo: linking to view-source:foo for reftests...
         return NS_OK;
     }
 
     // If we get here, check all the schemes can link to each other, from the top down:
     nsCaseInsensitiveCStringComparator stringComparator;
     nsCOMPtr<nsIURI> currentURI = sourceURI;
     nsCOMPtr<nsIURI> currentOtherURI = aTargetURI;
+
+    bool denySameSchemeLinks = false;
+    rv = NS_URIChainHasFlags(aTargetURI, nsIProtocolHandler::URI_SCHEME_NOT_SELF_LINKABLE,
+                             &denySameSchemeLinks);
+    if (NS_FAILED(rv)) return rv;
+
     while (currentURI && currentOtherURI) {
         nsAutoCString scheme, otherScheme;
         currentURI->GetScheme(scheme);
         currentOtherURI->GetScheme(otherScheme);
 
-        // If schemes are not equal, check if the URI flags of the current
-        // target URI allow the current source URI to link to it.
+        // If schemes are not equal, or they're equal but the target URI
+        // is different from the source URI and doesn't always allow linking
+        // from the same scheme, check if the URI flags of the current target
+        // URI allow the current source URI to link to it.
         // The policy is specified by the protocol flags on both URIs.
-        if (!scheme.Equals(otherScheme, stringComparator)) {
+        bool equalExceptRef = false;
+        if (!scheme.Equals(otherScheme, stringComparator) ||
+            (denySameSchemeLinks &&
+             (!NS_SUCCEEDED(currentURI->EqualsExceptRef(currentOtherURI, &equalExceptRef)) ||
+              !equalExceptRef))) {
             return CheckLoadURIFlags(currentURI, currentOtherURI,
                                      sourceBaseURI, targetBaseURI, aFlags);
         }
         // Otherwise... check if we can nest another level:
         nsCOMPtr<nsINestedURI> nestedURI = do_QueryInterface(currentURI);
         nsCOMPtr<nsINestedURI> nestedOtherURI = do_QueryInterface(currentOtherURI);
 
         // If schemes match and neither URI is nested further, we're OK.
--- a/netwerk/base/nsIProtocolHandler.idl
+++ b/netwerk/base/nsIProtocolHandler.idl
@@ -295,16 +295,22 @@ interface nsIProtocolHandler : nsISuppor
      */
     const unsigned long URI_FETCHABLE_BY_ANYONE = (1 << 19);
 
     /**
      * If this flag is set, then the origin for this protocol is the full URI
      * spec, not just the scheme + host + port.
      */
     const unsigned long ORIGIN_IS_FULL_SPEC = (1 << 20);
+
+    /**
+     * If this flag is set, the URI does not always allow content using the same
+     * protocol to link to it.
+     */
+    const unsigned long URI_SCHEME_NOT_SELF_LINKABLE = (1 << 21);
 };
 
 %{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
@@ -62,17 +62,17 @@ nsAboutProtocolHandler::GetDefaultPort(i
 {
     *result = -1;        // no port for about: URLs
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAboutProtocolHandler::GetProtocolFlags(uint32_t *result)
 {
-    *result = URI_NORELATIVE | URI_NOAUTH | URI_DANGEROUS_TO_LOAD;
+    *result = URI_NORELATIVE | URI_NOAUTH | URI_DANGEROUS_TO_LOAD | URI_SCHEME_NOT_SELF_LINKABLE;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAboutProtocolHandler::GetFlagsForURI(nsIURI* aURI, uint32_t* aFlags)
 {
     // First use the default (which is "unsafe for content"):
     GetProtocolFlags(aFlags);