Bug 656433: don't allow URIs loaded into the location bar to inherit the currently loaded document's principal, r=bz, r=dao
authorGavin Sharp <gavin@gavinsharp.com>
Thu, 12 May 2011 10:52:25 -0700
changeset 69582 5f42fe17284f9ee162895890ec723698c4ccd481
parent 69581 66f16e7dca6b6aa3f8ce8de9190f7675142b9bc9
child 69583 2c977d6f8a7591286adecdd0ea084f8528655fa8
push id20028
push usergsharp@mozilla.com
push dateMon, 16 May 2011 19:40:47 +0000
treeherdermozilla-central@2c977d6f8a75 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz, dao
bugs656433
milestone6.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 656433: don't allow URIs loaded into the location bar to inherit the currently loaded document's principal, r=bz, r=dao
browser/base/content/test/Makefile.in
browser/base/content/test/browser_locationBarExternalLoad.js
browser/base/content/urlbarBindings.xml
docshell/base/nsDocShell.cpp
docshell/base/nsIWebNavigation.idl
docshell/test/browser/Makefile.in
docshell/test/browser/browser_loadDisallowInherit.js
--- a/browser/base/content/test/Makefile.in
+++ b/browser/base/content/test/Makefile.in
@@ -195,16 +195,17 @@ endif
                  browser_scratchpad_initialization.js \
                  browser_scratchpad_contexts.js \
                  browser_scratchpad_execute_print.js \
                  browser_scratchpad_inspect.js \
                  browser_scratchpad_files.js \
                  browser_scratchpad_ui.js \
                  browser_scratchpad_bug_646070_chrome_context_pref.js \
                  browser_overflowScroll.js \
+                 browser_locationBarExternalLoad.js \
                  browser_pageInfo.js \
                  browser_page_style_menu.js \
                  browser_pinnedTabs.js \
                  browser_plainTextLinks.js \
                  browser_pluginnotification.js \
                  browser_relatedTabs.js \
                  browser_sanitize-passwordDisabledHosts.js \
                  browser_sanitize-sitepermissions.js \
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_locationBarExternalLoad.js
@@ -0,0 +1,51 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function test() {
+  waitForExplicitFinish();
+
+  nextTest();
+}
+
+let gTests = [
+// XXX bug 656815: javascript: URIs can't currently execute without inheriting
+// the page principal
+//  {
+//    url: "javascript:document.domain;"
+//  },
+  {
+    url: "data:text/html,<script>document.write(document.domain);</script>"
+  },
+];
+
+function nextTest() {
+  let test = gTests.shift();
+  if (test)
+    testURL(test.url, nextTest);
+  else
+    finish();
+}
+
+function testURL(newURL, func) {
+  let tab = gBrowser.selectedTab = gBrowser.addTab();
+  registerCleanupFunction(function () {
+    gBrowser.removeTab(tab);
+  });
+  addPageShowListener(function () {
+    let pagePrincipal = gBrowser.contentPrincipal;
+    gURLBar.value = newURL;
+    gURLBar.handleCommand();
+
+    addPageShowListener(function () {
+      ok(!gBrowser.contentPrincipal.equals(pagePrincipal), "load of " + newURL + " produced a page with a different principal");
+      func();
+    });
+  });
+}
+
+function addPageShowListener(func) {
+  gBrowser.selectedBrowser.addEventListener("pageshow", function loadListener() {
+    gBrowser.selectedBrowser.removeEventListener("pageshow", loadListener, false);
+    func();
+  });
+}
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -311,19 +311,23 @@
             this.handleRevert();
             content.focus();
             gBrowser.loadOneTab(url, {
                                 postData: postData,
                                 inBackground: false,
                                 allowThirdPartyFixup: true});
             aTriggeringEvent.preventDefault();
             aTriggeringEvent.stopPropagation();
+          } else {
+            // Pass LOAD_FLAGS_DISALLOW_INHERIT_OWNER to prevent any loads from
+            // inheriting the currently loaded document's principal.
+            let flags = Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP |
+                        Ci.nsIWebNavigation.LOAD_FLAGS_DISALLOW_INHERIT_OWNER;
+            gBrowser.loadURIWithFlags(url, flags, null, null, postData);
           }
-          else
-            loadURI(url, null, postData, true /* allow third party fixup */);
 
           gBrowser.selectedBrowser.focus();
         ]]></body>
       </method>
 
       <method name="_canonizeURL">
         <parameter name="aTriggeringEvent"/>
         <body><![CDATA[
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -1386,17 +1386,17 @@ nsDocShell::LoadURI(nsIURI * aURI,
         if (NS_FAILED(rv)) {
             // Set it back to false
             inheritOwner = PR_FALSE;
         }
     }
 
     PRUint32 flags = 0;
 
-    if (inheritOwner)
+    if (inheritOwner && !(aLoadFlags & LOAD_FLAGS_DISALLOW_INHERIT_OWNER))
         flags |= INTERNAL_LOAD_FLAGS_INHERIT_OWNER;
 
     if (!sendReferrer)
         flags |= INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER;
             
     if (aLoadFlags & LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP)
         flags |= INTERNAL_LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
 
--- a/docshell/base/nsIWebNavigation.idl
+++ b/docshell/base/nsIWebNavigation.idl
@@ -210,16 +210,21 @@ interface nsIWebNavigation : nsISupports
 
   /**
    * Force relevant cookies to be sent with this load even if normally they
    * wouldn't be.
    */
   const unsigned long LOAD_FLAGS_FORCE_ALLOW_COOKIES = 0x20000;
 
   /**
+   * Prevent the owner principal from being inherited for this load.
+   */
+  const unsigned long LOAD_FLAGS_DISALLOW_INHERIT_OWNER = 0x40000;
+
+  /**
    * Loads a given URI.  This will give priority to loading the requested URI
    * in the object implementing	this interface.  If it can't be loaded here
    * however, the URI dispatcher will go through its normal process of content
    * loading.
    *
    * @param aURI
    *        The URI string to load.  For HTTP and FTP URLs and possibly others,
    *        characters above U+007F will be converted to UTF-8 and then URL-
--- a/docshell/test/browser/Makefile.in
+++ b/docshell/test/browser/Makefile.in
@@ -47,14 +47,15 @@ include $(topsrcdir)/config/rules.mk
 		browser_bug92473.js \
 		test-form_sjis.html \
 		browser_bug134911.js \
 		browser_bug349769.js \
 		browser_bug388121-1.js \
 		browser_bug388121-2.js \
 		browser_bug441169.js \
 		browser_bug503832.js \
+		browser_loadDisallowInherit.js \
 		file_bug503832.html \
 		browser_bug554155.js \
 		$(NULL)
 
 libs:: $(_BROWSER_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/docshell/test/browser/browser_loadDisallowInherit.js
@@ -0,0 +1,48 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function test() {
+  waitForExplicitFinish();
+
+  let tab = gBrowser.selectedTab = gBrowser.addTab();
+  registerCleanupFunction(function () {
+    gBrowser.removeTab(tab);
+  });
+
+  let browser = gBrowser.getBrowserForTab(tab);
+
+  function loadURL(url, flags, func) {
+    browser.addEventListener("load", function loadListener(e) {
+      if (browser.currentURI.spec != url)
+        return;
+      browser.removeEventListener(e.type, loadListener, true);
+      func();
+    }, true);
+    browser.loadURIWithFlags(url, flags, null, null, null);
+  }
+
+  // Load a normal http URL
+  loadURL("http://example.com/", 0, function () {
+    let pagePrincipal = browser.contentPrincipal;
+
+    // Now load a data URI normally
+    loadURL("data:text/html,<body>inherit", 0, function () {
+      let dataPrincipal = browser.contentPrincipal;
+      ok(dataPrincipal.equals(pagePrincipal), "data URI should inherit principal");
+
+      // Load a normal http URL
+      loadURL("http://example.com/", 0, function () {
+        let innerPagePrincipal = browser.contentPrincipal;
+
+        // Now load a data URI and disallow inheriting the principal
+        let webNav = Components.interfaces.nsIWebNavigation;
+        loadURL("data:text/html,<body>noinherit", webNav.LOAD_FLAGS_DISALLOW_INHERIT_OWNER, function () {
+          let innerDataPrincipal = browser.contentPrincipal;
+          ok(!innerDataPrincipal.equals(innerPagePrincipal), "data URI should not inherit principal");
+
+          finish();
+        });
+      });
+    });
+  });
+}