Bug 1426767 - Disable login context menu items on documents with a null principal. r=Gijs
authorMatthew Noorenberghe <mozilla@noorenberghe.ca>
Tue, 02 Oct 2018 01:01:53 -0700
changeset 495229 0edeaf35b6e65757caeadee9ed6eb52feeaed0d7
parent 495228 d4a99f4598435e66d76dedd72558a494c73687fc
child 495230 8900229a39b1b2a783d310cd6795a878d62c621a
push id9984
push userffxbld-merge
push dateMon, 15 Oct 2018 21:07:35 +0000
treeherdermozilla-beta@183d27ea8570 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersGijs
bugs1426767
milestone64.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 1426767 - Disable login context menu items on documents with a null principal. r=Gijs Differential Revision: https://phabricator.services.mozilla.com/D7386
toolkit/components/passwordmgr/LoginManagerContent.jsm
toolkit/components/passwordmgr/test/browser/browser_context_menu_iframe.js
toolkit/components/passwordmgr/test/browser/form_basic_iframe.html
--- a/toolkit/components/passwordmgr/LoginManagerContent.jsm
+++ b/toolkit/components/passwordmgr/LoginManagerContent.jsm
@@ -1343,16 +1343,17 @@ var LoginManagerContent = {
    * @returns {Object} an object with information about the
    *                   FormLike username and password field
    *                   or null if the passed field is invalid.
    */
   getFieldContext(aField) {
     // If the element is not a proper form field, return null.
     if (ChromeUtils.getClassName(aField) !== "HTMLInputElement" ||
         (aField.type != "password" && !LoginHelper.isUsernameFieldType(aField)) ||
+        aField.nodePrincipal.isNullPrincipal ||
         !aField.ownerDocument) {
       return null;
     }
     let form = LoginFormFactory.createFromField(aField);
 
     let doc = aField.ownerDocument;
     let formOrigin = LoginUtils._getPasswordOrigin(doc.documentURI);
     let recipes = LoginRecipesContent.getRecipes(formOrigin, doc.defaultView);
--- a/toolkit/components/passwordmgr/test/browser/browser_context_menu_iframe.js
+++ b/toolkit/components/passwordmgr/test/browser/browser_context_menu_iframe.js
@@ -10,45 +10,41 @@ const TEST_HOSTNAME = "https://example.c
 const IFRAME_PAGE_PATH = "/browser/toolkit/components/passwordmgr/test/browser/form_basic_iframe.html";
 
 /**
  * Initialize logins needed for the tests and disable autofill
  * for login forms for easier testing of manual fill.
  */
 add_task(async function test_initialize() {
   Services.prefs.setBoolPref("signon.autofillForms", false);
+  Services.prefs.setBoolPref("signon.schemeUpgrades", true);
   registerCleanupFunction(() => {
     Services.prefs.clearUserPref("signon.autofillForms");
     Services.prefs.clearUserPref("signon.schemeUpgrades");
   });
   for (let login of loginList()) {
     Services.logins.addLogin(login);
   }
 });
 
 /**
  * Check if the password field is correctly filled when it's in an iframe.
  */
 add_task(async function test_context_menu_iframe_fill() {
-  Services.prefs.setBoolPref("signon.schemeUpgrades", true);
   await BrowserTestUtils.withNewTab({
     gBrowser,
     url: TEST_HOSTNAME + IFRAME_PAGE_PATH,
   }, async function(browser) {
-    function getPasswordInput() {
-      let frame = content.document.getElementById("test-iframe");
-      return frame.contentDocument.getElementById("form-basic-password");
-    }
-
     let contextMenuShownPromise = BrowserTestUtils.waitForEvent(window, "popupshown");
     let eventDetails = {type: "contextmenu", button: 2};
 
     // To click at the right point we have to take into account the iframe offset.
     // Synthesize a right mouse click over the password input element.
-    BrowserTestUtils.synthesizeMouseAtCenter(getPasswordInput, eventDetails, browser);
+    BrowserTestUtils.synthesizeMouseAtCenter(["#test-iframe", "#form-basic-password"],
+                                             eventDetails, browser);
     await contextMenuShownPromise;
 
     // Synthesize a mouse click over the fill login menu header.
     let popupHeader = document.getElementById("fill-login");
     let popupShownPromise = BrowserTestUtils.waitForEvent(popupHeader, "popupshown");
     EventUtils.synthesizeMouseAtCenter(popupHeader, {});
     await popupShownPromise;
 
@@ -87,16 +83,62 @@ add_task(async function test_context_men
        "Username value was not changed.");
 
     let contextMenu = document.getElementById("contentAreaContextMenu");
     contextMenu.hidePopup();
   });
 });
 
 /**
+ * Check that the login context menu items don't appear on an opaque origin.
+ */
+add_task(async function test_context_menu_iframe_sandbox() {
+  await BrowserTestUtils.withNewTab({
+    gBrowser,
+    url: TEST_HOSTNAME + IFRAME_PAGE_PATH,
+  }, async function(browser) {
+    let contextMenuShownPromise = BrowserTestUtils.waitForEvent(window, "popupshown");
+    let eventDetails = {type: "contextmenu", button: 2};
+
+    BrowserTestUtils.synthesizeMouseAtCenter(["#test-iframe-sandbox", "#form-basic-password"],
+                                             eventDetails, browser);
+    await contextMenuShownPromise;
+
+    let popupHeader = document.getElementById("fill-login");
+    ok(popupHeader.disabled, "Check that the Fill Login menu item is disabled");
+
+    let contextMenu = document.getElementById("contentAreaContextMenu");
+    contextMenu.hidePopup();
+  });
+});
+
+/**
+ * Check that the login context menu item appears for sandbox="allow-same-origin"
+ */
+add_task(async function test_context_menu_iframe_sandbox_same_origin() {
+  await BrowserTestUtils.withNewTab({
+    gBrowser,
+    url: TEST_HOSTNAME + IFRAME_PAGE_PATH,
+  }, async function(browser) {
+    let contextMenuShownPromise = BrowserTestUtils.waitForEvent(window, "popupshown");
+    let eventDetails = {type: "contextmenu", button: 2};
+
+    BrowserTestUtils.synthesizeMouseAtCenter(["#test-iframe-sandbox-same-origin", "#form-basic-password"],
+                                             eventDetails, browser);
+    await contextMenuShownPromise;
+
+    let popupHeader = document.getElementById("fill-login");
+    ok(!popupHeader.disabled, "Check that the Fill Login menu item is enabled");
+
+    let contextMenu = document.getElementById("contentAreaContextMenu");
+    contextMenu.hidePopup();
+  });
+});
+
+/**
  * Search for a login by it's username.
  *
  * Only unique login/hostname combinations should be used at this test.
  */
 function getLoginFromUsername(username) {
   return loginList().find(login => login.username == username);
 }
 
--- a/toolkit/components/passwordmgr/test/browser/form_basic_iframe.html
+++ b/toolkit/components/passwordmgr/test/browser/form_basic_iframe.html
@@ -3,11 +3,21 @@
 
 <head>
     <meta charset="utf-8">
 </head>
 
 <body>
     <!-- Form in an iframe -->
     <iframe src="https://example.org/browser/toolkit/components/passwordmgr/test/browser/form_basic.html" id="test-iframe"></iframe>
+
+    <!-- Form in a fully sandboxed iframe -->
+    <iframe src="https://example.org/browser/toolkit/components/passwordmgr/test/browser/form_basic.html"
+            sandbox=""
+            id="test-iframe-sandbox"></iframe>
+
+    <!-- Form in an "allow-same-origin" sandboxed iframe -->
+    <iframe src="https://example.org/browser/toolkit/components/passwordmgr/test/browser/form_basic.html"
+            sandbox="allow-same-origin"
+            id="test-iframe-sandbox-same-origin"></iframe>
 </body>
 
 </html>