Bug 1550143 - Open links included in the abuse report panel using a null triggeringPrincipal. r=mstriemer,jaws
authorLuca Greco <lgreco@mozilla.com>
Fri, 17 May 2019 10:41:11 +0000
changeset 474374 e5a6c78aa9a36747bfcae767d654bd0b35833bea
parent 474373 7e8007308d0daeaf79f9ef9efe642e4ac0fb1941
child 474375 8c01df028cc2b49c54e1216a4b2c562e23ea2dfe
push id113152
push userdluca@mozilla.com
push dateSat, 18 May 2019 10:33:03 +0000
treeherdermozilla-inbound@9b2f851979cb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstriemer, jaws
bugs1550143
milestone68.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 1550143 - Open links included in the abuse report panel using a null triggeringPrincipal. r=mstriemer,jaws Differential Revision: https://phabricator.services.mozilla.com/D30400
toolkit/mozapps/extensions/content/abuse-report-panel.js
toolkit/mozapps/extensions/test/browser/browser_html_abuse_report.js
--- a/toolkit/mozapps/extensions/content/abuse-report-panel.js
+++ b/toolkit/mozapps/extensions/content/abuse-report-panel.js
@@ -463,16 +463,27 @@ class AbuseReport extends HTMLElement {
           this.switchToSubmitMode();
         }
         if (evt.target === this._btnGoBack) {
           this.switchToListMode();
         }
         if (evt.target === this._btnSubmit) {
           this.submit();
         }
+        if (evt.target.localName === "a") {
+          evt.preventDefault();
+          evt.stopPropagation();
+          const url = evt.target.getAttribute("href");
+          // Ignore if url is empty.
+          if (url) {
+            window.windowRoot.ownerGlobal.openWebLinkIn(url, "tab", {
+              relatedToCurrent: true,
+            });
+          }
+        }
         break;
     }
   }
 
   render() {
     this.textContent = "";
     this.appendChild(document.importNode(this.template.content, true));
   }
@@ -623,35 +634,35 @@ class AbuseReport extends HTMLElement {
   }
 
   get addonCreator() {
     return this.addon && this.addon.creator;
   }
 
   get homepageURL() {
     const {addon} = this;
-    return addon && addon.homepageURL || this.authorURL;
+    return addon && addon.homepageURL || this.authorURL || "";
   }
 
   get authorName() {
     // The author name may be missing on some of the test extensions
     // (or for temporarily installed add-ons).
     return this.addonCreator && this.addonCreator.name || "";
   }
 
   get authorURL() {
-    return this.addonCreator && this.addonCreator.url;
+    return this.addonCreator && this.addonCreator.url || "";
   }
 
   get iconURL() {
     return this.addon && this.addon.iconURL;
   }
 
   get supportURL() {
-    return this.addon && this.addon.supportURL || this.homepageURL;
+    return this.addon && this.addon.supportURL || this.homepageURL || "";
   }
 
   get message() {
     return this._form.elements.message.value;
   }
 
   get reason() {
     return this._form.elements.reason.value;
--- a/toolkit/mozapps/extensions/test/browser/browser_html_abuse_report.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_html_abuse_report.js
@@ -21,16 +21,17 @@ const BASE_TEST_MANIFEST = {
   name: "Fake extension to report",
   author: "Fake author",
   homepage_url: "https://fake.extension.url/",
   applications: {gecko: {id: ADDON_ID}},
   icons: {
     32: "test-icon.png",
   },
 };
+const EXT_WITH_PRIVILEGED_URL_ID = "ext-with-privileged-url@mochi.test";
 const THEME_NO_UNINSTALL_ID = "theme-without-perm-can-uninstall@mochi.test";
 
 let gProvider;
 let gHtmlAboutAddonsWindow;
 let gManagerWindow;
 let apiRequestHandler;
 
 AddonTestUtils.initMochitest(this);
@@ -220,16 +221,22 @@ add_task(async function setup() {
   gProvider = new MockProvider();
   gProvider.createAddons([{
     id: THEME_NO_UNINSTALL_ID,
     name: "This theme cannot be uninstalled",
     version: "1.1",
     creator: {name: "Theme creator", url: "http://example.com/creator"},
     type: "theme",
     permissions: 0,
+  }, {
+    id: EXT_WITH_PRIVILEGED_URL_ID,
+    name: "This extension has an unexpected privileged creator URL",
+    version: "1.1",
+    creator: {name: "creator", url: "about:config"},
+    type: "extension",
   }]);
 });
 
 // This test case verifies that:
 // - the about:addons XUL page contains the addon-abuse-report-xulframe element,
 //   and that
 //   it is part of a XUL stack alongside with the rest of a about:addons
 //   XUL page
@@ -988,41 +995,75 @@ add_task(async function test_trigger_abu
   const extension = await installTestExtension(EXT_ID, "extension", {
     browser_action: {},
   });
 
   // Prepare the mocked prompt service.
   const promptService = mockPromptService();
   promptService.confirmEx = createPromptConfirmEx({remove: true, report: true});
 
-  info(`Open browserAction context menu in toolbar context menu`);
-  let buttonId = `${makeWidgetId(EXT_ID)}-browser-action`;
-  const menu = document.getElementById("toolbar-context-menu");
-  const node = document.getElementById(CSS.escape(buttonId));
-  const shown = BrowserTestUtils.waitForEvent(menu, "popupshown");
-  EventUtils.synthesizeMouseAtCenter(node, {type: "contextmenu"});
-  await shown;
+  await BrowserTestUtils.withNewTab("about:blank", async function() {
+    info(`Open browserAction context menu in toolbar context menu`);
+    let buttonId = `${makeWidgetId(EXT_ID)}-browser-action`;
+    const menu = document.getElementById("toolbar-context-menu");
+    const node = document.getElementById(CSS.escape(buttonId));
+    const shown = BrowserTestUtils.waitForEvent(menu, "popupshown");
+    EventUtils.synthesizeMouseAtCenter(node, {type: "contextmenu"});
+    await shown;
 
-  info(`Clicking on "Remove Extension" context menu item`);
-  let removeExtension = menu.querySelector(
-    ".customize-context-removeExtension");
-  removeExtension.click();
+    info(`Clicking on "Remove Extension" context menu item`);
+    let removeExtension = menu.querySelector(
+      ".customize-context-removeExtension");
+    removeExtension.click();
 
-  // Wait about:addons to be loaded.
-  const browser = gBrowser.selectedBrowser;
-  await BrowserTestUtils.browserLoaded(browser);
-  is(browser.currentURI.spec, "about:addons",
-    "about:addons tab currently selected");
-  menu.hidePopup();
+    // Wait about:addons to be loaded.
+    const browser = gBrowser.selectedBrowser;
+    await BrowserTestUtils.browserLoaded(browser);
+    is(browser.currentURI.spec, "about:addons",
+      "about:addons tab currently selected");
+    menu.hidePopup();
 
-  const abuseReportFrame = browser.contentDocument
-    .querySelector("addon-abuse-report-xulframe");
+    const abuseReportFrame = browser.contentDocument
+      .querySelector("addon-abuse-report-xulframe");
 
-  ok(!abuseReportFrame.hidden,
-     "Abuse report frame has the expected visibility");
-  is(abuseReportFrame.report.addon.id, EXT_ID,
-    "Abuse report frame has the expected addon id");
-  is(abuseReportFrame.report.reportEntryPoint, "uninstall",
-    "Abuse report frame has the expected reportEntryPoint");
+    ok(!abuseReportFrame.hidden,
+      "Abuse report frame has the expected visibility");
+    is(abuseReportFrame.report.addon.id, EXT_ID,
+      "Abuse report frame has the expected addon id");
+    is(abuseReportFrame.report.reportEntryPoint, "uninstall",
+      "Abuse report frame has the expected reportEntryPoint");
+  });
 
-  await closeAboutAddons();
   await extension.unload();
 });
+
+// This test verify that the abuse report panel is opening the
+// author link using a null triggeringPrincipal.
+add_task(async function test_abuse_report_open_author_url() {
+  const abuseReportEl = await openAbuseReport(EXT_WITH_PRIVILEGED_URL_ID);
+  await promiseAbuseReportRendered(abuseReportEl);
+
+  const authorLink = abuseReportEl._linkAddonAuthor;
+  ok(authorLink, "Got the author link element");
+  is(authorLink.href, "about:config",
+     "Got a privileged url in the link element");
+
+  SimpleTest.waitForExplicitFinish();
+  let waitForConsole = new Promise(resolve => {
+    SimpleTest.monitorConsole(resolve, [{
+      // eslint-disable-next-line max-len
+      message: /Security Error: Content at moz-nullprincipal:{.*} may not load or link to about:config/,
+    }]);
+  });
+
+  let tabSwitched = BrowserTestUtils.waitForEvent(gBrowser, "TabSwitchDone");
+  authorLink.click();
+  await tabSwitched;
+
+  is(gBrowser.selectedBrowser.currentURI.spec, "about:blank",
+     "Got about:blank loaded in the new tab");
+
+  SimpleTest.endMonitorConsole();
+  await waitForConsole;
+
+  BrowserTestUtils.removeTab(gBrowser.selectedTab);
+  await closeAboutAddons();
+});