mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-24 19:37:15 +00:00
Bug 1760608 - Restrict MV2 pageAction/browserAction setPopup to same extension urls on GeckoView. r=mixedpuppy,geckoview-reviewers,owlish
This patch extends restricts setPopup to extension url to MV2 extensions running on GeckoView. Differential Revision: https://phabricator.services.mozilla.com/D154549
This commit is contained in:
parent
28400cd40e
commit
9efa813720
@ -157,6 +157,10 @@ pref("xpinstall.signatures.required", true);
|
||||
// Use blocklist v2 until blocklist v3 is enabled on Android - bug 1639050
|
||||
pref("extensions.blocklist.useMLBF", false);
|
||||
|
||||
// Whether MV3 restrictions for actions popup urls should be extended to MV2 extensions
|
||||
// (only allowing same extension urls to be used as action popup urls).
|
||||
pref("extensions.manifestV2.actionsPopupURLRestricted", true);
|
||||
|
||||
// Disable add-ons that are not installed by the user in all scopes by default (See the SCOPE
|
||||
// constants in AddonManager.jsm for values to use here, and Bug 1405528 for a rationale).
|
||||
pref("extensions.autoDisableScopes", 15);
|
||||
|
@ -36,6 +36,31 @@ function handlePageActionMessage(message, tabId) {
|
||||
});
|
||||
break;
|
||||
|
||||
case "setPopupCheckRestrictions":
|
||||
browser.pageAction
|
||||
.setPopup({
|
||||
tabId,
|
||||
popup: message.popup,
|
||||
})
|
||||
.then(
|
||||
() => {
|
||||
port.postMessage({
|
||||
resultFor: "setPopup",
|
||||
type: "pageAction",
|
||||
success: true,
|
||||
});
|
||||
},
|
||||
err => {
|
||||
port.postMessage({
|
||||
resultFor: "setPopup",
|
||||
type: "pageAction",
|
||||
success: false,
|
||||
error: String(err),
|
||||
});
|
||||
}
|
||||
);
|
||||
break;
|
||||
|
||||
case "setTitle":
|
||||
browser.pageAction.setTitle({
|
||||
tabId,
|
||||
@ -94,6 +119,31 @@ function handleBrowserActionMessage(message, tabId) {
|
||||
});
|
||||
break;
|
||||
|
||||
case "setPopupCheckRestrictions":
|
||||
browser.browserAction
|
||||
.setPopup({
|
||||
tabId,
|
||||
popup: message.popup,
|
||||
})
|
||||
.then(
|
||||
() => {
|
||||
port.postMessage({
|
||||
resultFor: "setPopup",
|
||||
type: "browserAction",
|
||||
success: true,
|
||||
});
|
||||
},
|
||||
err => {
|
||||
port.postMessage({
|
||||
resultFor: "setPopup",
|
||||
type: "browserAction",
|
||||
success: false,
|
||||
error: String(err),
|
||||
});
|
||||
}
|
||||
);
|
||||
break;
|
||||
|
||||
case "setTitle":
|
||||
browser.browserAction.setTitle({
|
||||
tabId,
|
||||
|
@ -26,6 +26,7 @@ import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.AssertCalled
|
||||
@RunWith(Parameterized::class)
|
||||
class ExtensionActionTest : BaseSessionTest() {
|
||||
private var extension: WebExtension? = null
|
||||
private var otherExtension: WebExtension? = null
|
||||
private var default: WebExtension.Action? = null
|
||||
private var backgroundPort: WebExtension.Port? = null
|
||||
private var windowPort: WebExtension.Port? = null
|
||||
@ -57,6 +58,10 @@ class ExtensionActionTest : BaseSessionTest() {
|
||||
|
||||
extension = sessionRule.waitForResult(
|
||||
controller.installBuiltIn("resource://android/assets/web_extensions/actions/"));
|
||||
// Another dummy extension, only used to check restrictions related to setting
|
||||
// another extension url as a popup url, and so there is no delegate needed for it.
|
||||
otherExtension = sessionRule.waitForResult(
|
||||
controller.installBuiltIn("resource://android/assets/web_extensions/dummy/"));
|
||||
|
||||
mainSession.webExtensionController.setMessageDelegate(
|
||||
extension!!,
|
||||
@ -123,6 +128,10 @@ class ExtensionActionTest : BaseSessionTest() {
|
||||
extension!!.setActionDelegate(null)
|
||||
sessionRule.waitForResult(controller.uninstall(extension!!))
|
||||
}
|
||||
|
||||
if (otherExtension != null) {
|
||||
sessionRule.waitForResult(controller.uninstall(otherExtension!!))
|
||||
}
|
||||
}
|
||||
|
||||
private fun testBackgroundActionApi(message: String, tester: (WebExtension.Action) -> Unit) {
|
||||
@ -163,6 +172,43 @@ class ExtensionActionTest : BaseSessionTest() {
|
||||
sessionRule.waitForResult(result)
|
||||
}
|
||||
|
||||
private fun testSetPopup(popupUrl: String, isUrlAllowed: Boolean) {
|
||||
val setPopupResult = GeckoResult<Void>()
|
||||
|
||||
backgroundPort!!.setDelegate(object : WebExtension.PortDelegate {
|
||||
override fun onPortMessage(message: Any, port: WebExtension.Port) {
|
||||
val json = message as JSONObject
|
||||
if (json.getString("resultFor") == "setPopup" &&
|
||||
json.getString("type") == type) {
|
||||
if (isUrlAllowed != json.getBoolean("success")) {
|
||||
val expectedResString = when(isUrlAllowed) {
|
||||
true -> "allowed"
|
||||
else -> "disallowed"
|
||||
};
|
||||
setPopupResult.completeExceptionally(IllegalArgumentException(
|
||||
"Expected \"${popupUrl}\" to be ${ expectedResString }"))
|
||||
} else {
|
||||
setPopupResult.complete(null)
|
||||
}
|
||||
} else {
|
||||
// We should NOT receive the expected message result.
|
||||
setPopupResult.completeExceptionally(IllegalArgumentException(
|
||||
"Received unexpected result for: ${json.getString("type")} ${json.getString("resultFor")}"))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
var json = JSONObject("""{
|
||||
"action": "setPopupCheckRestrictions",
|
||||
"popup": "$popupUrl"
|
||||
}""");
|
||||
|
||||
json.put("type", type)
|
||||
windowPort!!.postMessage(json)
|
||||
|
||||
sessionRule.waitForResult(setPopupResult)
|
||||
}
|
||||
|
||||
private fun testActionApi(message: String, tester: (WebExtension.Action) -> Unit) {
|
||||
val result = GeckoResult<Void>()
|
||||
|
||||
@ -477,6 +523,15 @@ class ExtensionActionTest : BaseSessionTest() {
|
||||
sessionRule.waitForResult(error)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSetPopupRestrictions() {
|
||||
testSetPopup("https://example.com", false)
|
||||
testSetPopup("${otherExtension!!.metaData.baseUrl}other-extension.html", false)
|
||||
testSetPopup("${extension!!.metaData.baseUrl}same-extension.html", true)
|
||||
testSetPopup("relative-url-01.html", true);
|
||||
testSetPopup("/relative-url-02.html", true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@GeckoSessionTestRule.WithDisplay(width=100, height=100)
|
||||
fun testOpenPopup() {
|
||||
|
@ -2079,6 +2079,9 @@ pref("extensions.blocklist.addonItemURL", "https://addons.mozilla.org/%LOCALE%/%
|
||||
pref("extensions.blocklist.level", 2);
|
||||
// Whether event pages should be enabled for "manifest_version: 2" extensions.
|
||||
pref("extensions.eventPages.enabled", false);
|
||||
// Whether MV3 restrictions for actions popup urls should be extended to MV2 extensions
|
||||
// (only allowing same extension urls to be used as action popup urls).
|
||||
pref("extensions.manifestV2.actionsPopupURLRestricted", false);
|
||||
// Whether "manifest_version: 3" extensions should be allowed to install successfully.
|
||||
pref("extensions.manifestV3.enabled", false);
|
||||
// Whether to enable the unified extensions feature.
|
||||
|
@ -16,6 +16,19 @@ const { ExtensionParent } = ChromeUtils.import(
|
||||
);
|
||||
const { IconDetails, StartupCache } = ExtensionParent;
|
||||
|
||||
const { XPCOMUtils } = ChromeUtils.importESModule(
|
||||
"resource://gre/modules/XPCOMUtils.sys.mjs"
|
||||
);
|
||||
|
||||
const lazy = {};
|
||||
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
lazy,
|
||||
"MV2_ACTION_POPURL_RESTRICTED",
|
||||
"extensions.manifestV2.actionsPopupURLRestricted",
|
||||
false
|
||||
);
|
||||
|
||||
function parseColor(color, kind) {
|
||||
if (typeof color == "string") {
|
||||
let rgba = InspectorUtils.colorToRGBA(color);
|
||||
@ -265,10 +278,18 @@ class PanelActionBase {
|
||||
|
||||
// On manifest_version 3 is mandatory for the resolved URI to belong to the
|
||||
// current extension (see Bug 1760608).
|
||||
//
|
||||
// The same restriction is extended extend to MV2 extensions if the
|
||||
// "extensions.manifestV2.actionsPopupURLRestricted" preference is set to true.
|
||||
//
|
||||
// (Currently set to true by default on GeckoView builds, where the set of
|
||||
// extensions supported is limited to a small set and so less risks of
|
||||
// unexpected regressions for the existing extensions).
|
||||
if (
|
||||
context.extension.manifestVersion >= 3 &&
|
||||
url &&
|
||||
!url.startsWith(extension.baseURI.spec)
|
||||
!url.startsWith(extension.baseURI.spec) &&
|
||||
(context.extension.manifestVersion >= 3 ||
|
||||
lazy.MV2_ACTION_POPURL_RESTRICTED)
|
||||
) {
|
||||
return Promise.reject({ message: `Access denied for URL ${url}` });
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user