Bug 1380597 - Ensure the url can be loaded by the extension. r=kmag
authorShane Caraveo <scaraveo@mozilla.com>
Thu, 07 Sep 2017 17:09:40 -0400
changeset 429119 446798b4fc37aa40e1a626d0840057d4f805764b
parent 429118 84760282660db7bbe97ce7ffb3ed361d6ad02ba3
child 429120 1c4bb93c75ae9c8779ce18aed398f469a1616704
push id7761
push userjlund@mozilla.com
push dateFri, 15 Sep 2017 00:19:52 +0000
treeherdermozilla-beta@c38455951db4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskmag
bugs1380597
milestone57.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 1380597 - Ensure the url can be loaded by the extension. r=kmag MozReview-Commit-ID: GH31FlHxpVu
browser/components/extensions/ext-browserAction.js
browser/components/extensions/ext-pageAction.js
browser/components/extensions/ext-sidebarAction.js
browser/components/extensions/schemas/page_action.json
browser/components/extensions/test/browser/browser_ext_browserAction_context.js
browser/components/extensions/test/browser/browser_ext_pageAction_context.js
browser/components/extensions/test/browser/browser_ext_sidebarAction_context.js
--- a/browser/components/extensions/ext-browserAction.js
+++ b/browser/components/extensions/ext-browserAction.js
@@ -643,16 +643,19 @@ this.browserAction = class extends Exten
           let tab = getTab(details.tabId);
 
           // Note: Chrome resolves arguments to setIcon relative to the calling
           // context, but resolves arguments to setPopup relative to the extension
           // root.
           // For internal consistency, we currently resolve both relative to the
           // calling context.
           let url = details.popup && context.uri.resolve(details.popup);
+          if (url && !context.checkLoadURL(url)) {
+            return Promise.reject({message: `Access denied for URL ${url}`});
+          }
           browserAction.setProperty(tab, "popup", url);
         },
 
         getPopup: function(details) {
           let tab = getTab(details.tabId);
 
           let popup = browserAction.getProperty(tab, "popup");
           return Promise.resolve(popup);
--- a/browser/components/extensions/ext-pageAction.js
+++ b/browser/components/extensions/ext-pageAction.js
@@ -324,16 +324,19 @@ this.pageAction = class extends Extensio
           let tab = tabTracker.getTab(details.tabId);
 
           // Note: Chrome resolves arguments to setIcon relative to the calling
           // context, but resolves arguments to setPopup relative to the extension
           // root.
           // For internal consistency, we currently resolve both relative to the
           // calling context.
           let url = details.popup && context.uri.resolve(details.popup);
+          if (url && !context.checkLoadURL(url)) {
+            return Promise.reject({message: `Access denied for URL ${url}`});
+          }
           pageAction.setProperty(tab, "popup", url);
         },
 
         getPopup(details) {
           let tab = tabTracker.getTab(details.tabId);
 
           let popup = pageAction.getProperty(tab, "popup");
           return Promise.resolve(popup);
--- a/browser/components/extensions/ext-sidebarAction.js
+++ b/browser/components/extensions/ext-sidebarAction.js
@@ -412,16 +412,19 @@ this.sidebarAction = class extends Exten
           let nativeTab = getTab(details.tabId);
 
           let url;
           // Clear the tab-specific url when given a null string.
           if (nativeTab && details.panel === "") {
             url = null;
           } else if (details.panel !== "") {
             url = context.uri.resolve(details.panel);
+            if (!context.checkLoadURL(url)) {
+              return Promise.reject({message: `Access denied for URL ${url}`});
+            }
           } else {
             throw new ExtensionError("Invalid url for sidebar panel.");
           }
 
           sidebarAction.setProperty(nativeTab, "panel", url);
         },
 
         getPanel(details) {
--- a/browser/components/extensions/schemas/page_action.json
+++ b/browser/components/extensions/schemas/page_action.json
@@ -172,16 +172,17 @@
             "optional": true,
             "parameters": []
           }
         ]
       },
       {
         "name": "setPopup",
         "type": "function",
+        "async": true,
         "description": "Sets the html document to be opened as a popup when the user clicks on the page action's icon.",
         "parameters": [
           {
             "name": "details",
             "type": "object",
             "properties": {
               "tabId": {"type": "integer", "minimum": 0, "description": "The id of the tab for which you want to modify the page action."},
               "popup": {
--- a/browser/components/extensions/test/browser/browser_ext_browserAction_context.js
+++ b/browser/components/extensions/test/browser/browser_ext_browserAction_context.js
@@ -389,12 +389,21 @@ add_task(async function testDefaultTitle
         },
         async expect => {
           browser.test.log("Set default title to null string. Expect null string from API, extension title in UI.");
           browser.browserAction.setTitle({title: ""});
 
           await expectDefaults(details[3]);
           expect(details[3]);
         },
+        async expect => {
+          browser.test.assertRejects(
+            browser.browserAction.setPopup({popup: "about:addons"}),
+            /Access denied for URL about:addons/,
+            "unable to set popup to about:addons");
+
+          await expectDefaults(details[3]);
+          expect(details[3]);
+        },
       ];
     },
   });
 });
--- a/browser/components/extensions/test/browser/browser_ext_pageAction_context.js
+++ b/browser/components/extensions/test/browser/browser_ext_pageAction_context.js
@@ -165,12 +165,20 @@ add_task(async function testTabSwitchCon
           expect(details[1]);
         },
         async expect => {
           browser.test.log("Hide the icon. Expect hidden.");
 
           await browser.pageAction.hide(tabs[0]);
           expect(null);
         },
+        async expect => {
+          browser.test.assertRejects(
+            browser.pageAction.setPopup({tabId: tabs[0], popup: "about:addons"}),
+            /Access denied for URL about:addons/,
+            "unable to set popup to about:addons");
+
+          expect(null);
+        },
       ];
     },
   });
 });
--- a/browser/components/extensions/test/browser/browser_ext_sidebarAction_context.js
+++ b/browser/components/extensions/test/browser/browser_ext_sidebarAction_context.js
@@ -370,12 +370,21 @@ add_task(async function testDefaultTitle
         },
         async expect => {
           browser.test.log("Set default title to null string. Expect null string from API, extension title in UI.");
           browser.sidebarAction.setTitle({title: ""});
 
           await expectDefaults(details[3]);
           expect(details[3]);
         },
+        async expect => {
+          browser.test.assertRejects(
+            browser.sidebarAction.setPanel({panel: "about:addons"}),
+            /Access denied for URL about:addons/,
+            "unable to set panel to about:addons");
+
+          await expectDefaults(details[3]);
+          expect(details[3]);
+        },
       ];
     },
   });
 });