feat: Allow installing add-ons from addons.mozilla.org without the privileged mozAddonManager API (Like Desktop), and disable mozAddonManager by default

Signed-off-by: celenity <celenity@celenity.dev>
This commit is contained in:
celenity
2025-06-04 01:11:56 -04:00
parent 9a021a11a5
commit 00ecde85e2
5 changed files with 104 additions and 51 deletions

View File

@@ -330,7 +330,7 @@ Changes to patches are licensed according to the header in the files this patch
Parts of `branding.patch`, `librewolf-rs-blocker.patch`, and `ublock-assets.patch`, are adapted from [LibreWolf](https://librewolf.net/). See [LibreWolf License and Disclaimers](https://librewolf.net/license-disclaimers/).
`tor-spoof-english.patch` is adapted from the [Tor Project](hhttps://www.torproject.org/). See [LICENSE](https://gitlab.torproject.org/tpo/core/tor/-/raw/HEAD/LICENSE).
`install-addons-from-amo-without-mozaddonmanager.patch` and `tor-spoof-english.patch` are adapted from the [Tor Project](hhttps://www.torproject.org/). See [LICENSE](https://gitlab.torproject.org/tpo/core/tor/-/raw/HEAD/LICENSE).
## Notices

View File

@@ -0,0 +1,91 @@
diff --git a/toolkit/mozapps/extensions/AddonManager.sys.mjs b/toolkit/mozapps/extensions/AddonManager.sys.mjs
index e09ea87de8..9c230f27db 100644
--- a/toolkit/mozapps/extensions/AddonManager.sys.mjs
+++ b/toolkit/mozapps/extensions/AddonManager.sys.mjs
@@ -84,6 +84,8 @@ const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
AbuseReporter: "resource://gre/modules/AbuseReporter.sys.mjs",
AddonRepository: "resource://gre/modules/addons/AddonRepository.sys.mjs",
+ GeckoViewWebExtension: "resource://gre/modules/GeckoViewWebExtension.sys.mjs",
+ EventDispatcher: "resource://gre/modules/Messaging.sys.mjs",
Extension: "resource://gre/modules/Extension.sys.mjs",
RemoteSettings: "resource://services-settings/remote-settings.sys.mjs",
TelemetryTimestamps: "resource://gre/modules/TelemetryTimestamps.sys.mjs",
@@ -2346,6 +2348,22 @@ var AddonManagerInternal = {
return promiseInstall;
},
+ async installGeckoViewWebExtension(extensionUri) {
+ const installId = Services.uuid.generateUUID().toString();
+ let { extension } = await lazy.GeckoViewWebExtension.installWebExtension(
+ installId,
+ extensionUri
+ );
+ if (extension) {
+ await lazy.EventDispatcher.instance.sendRequest({
+ type: "GeckoView:WebExtension:OnInstalled",
+ extension,
+ });
+ } else {
+ console.error("Failed to install the extension: extension is null.");
+ }
+ },
+
/**
* Starts installation of an AddonInstall notifying the registered
* web install listener of a blocked or started install.
@@ -2518,6 +2536,11 @@ var AddonManagerInternal = {
);
if (installAllowed) {
+ if (AppConstants.platform == "android") {
+ aInstall.cancel();
+ this.installGeckoViewWebExtension(aInstall.sourceURI);
+ return;
+ }
startInstall("AMO");
} else if (installPerm === Ci.nsIPermissionManager.DENY_ACTION) {
// Block without prompt
diff --git a/toolkit/mozapps/extensions/components.conf b/toolkit/mozapps/extensions/components.conf
index 680aa57c07..1d0ce25519 100644
--- a/toolkit/mozapps/extensions/components.conf
+++ b/toolkit/mozapps/extensions/components.conf
@@ -32,14 +32,10 @@ Classes = [
'esModule': 'resource://gre/modules/amWebAPI.sys.mjs',
'constructor': 'WebAPI',
},
+ {
+ 'cid': '{7beb3ba8-6ec3-41b4-b67c-da89b8518922}',
+ 'contract_ids': ['@mozilla.org/uriloader/content-handler;1?type=application/x-xpinstall'],
+ 'esModule': 'resource://gre/modules/amContentHandler.sys.mjs',
+ 'constructor': 'amContentHandler',
+ },
]
-
-if buildconfig.substs['MOZ_WIDGET_TOOLKIT'] != 'android':
- Classes += [
- {
- 'cid': '{7beb3ba8-6ec3-41b4-b67c-da89b8518922}',
- 'contract_ids': ['@mozilla.org/uriloader/content-handler;1?type=application/x-xpinstall'],
- 'esModule': 'resource://gre/modules/amContentHandler.sys.mjs',
- 'constructor': 'amContentHandler',
- },
- ]
diff --git a/toolkit/mozapps/extensions/internal/XPIInstall.sys.mjs b/toolkit/mozapps/extensions/internal/XPIInstall.sys.mjs
index 03c4f77791..34891b361c 100644
--- a/toolkit/mozapps/extensions/internal/XPIInstall.sys.mjs
+++ b/toolkit/mozapps/extensions/internal/XPIInstall.sys.mjs
@@ -4477,6 +4477,13 @@ export var XPIInstall = {
return false;
}
+ if (
+ AppConstants.platform == "android" &&
+ uri.prePath == "https://addons.mozilla.org"
+ ) {
+ return true;
+ }
+
let requireWhitelist = Services.prefs.getBoolPref(
PREF_XPI_WHITELIST_REQUIRED,
true

View File

@@ -11,6 +11,14 @@ pref("privacy.fingerprintingProtection.overrides", ""); // [DEFAULT]
// We're including these internally with a custom Remote Settings dump instead of setting them here, which makes it far easier for users to add their own overrides if desired (by using this preference).
pref("privacy.fingerprintingProtection.granularOverrides", ''); // [DEFAULT]
/// Disable mozAddonManager
// mozAddonManager prevents extensions from working on `addons.mozilla.org`, and this API also exposes a list of the user's installed add-ons to `addons.mozilla.org`
// Disabling the following preferences typically breaks installation of extensions from `addons.mozilla.org` on Android, but we fix this with our `install-addons-from-amo-without-mozaddonmanager` patch.
// https://bugzilla.mozilla.org/show_bug.cgi?id=1952390#c4
// https://bugzilla.mozilla.org/show_bug.cgi?id=1384330
pref("extensions.webapi.enabled", false);
pref("privacy.resistFingerprinting.block_mozAddonManager", true);
/// Re-enable the use of Cookie Banner Reduction rules from Remote Settings
// We disable this functionality in Phoenix and instead set the rules locally via the "cookiebanners.listService.testRules" pref
// We include the Cookie Banner Reduction rules local dump though, so we can just leave this on, but block remotely fetching the rules with the "browser.ironfox.services.settings.allowedCollections" pref instead

View File

@@ -1,46 +0,0 @@
diff --git a/toolkit/mozapps/extensions/amManager.sys.mjs b/toolkit/mozapps/extensions/amManager.sys.mjs
index 3d9f3e6b40..aa1ed91690 100644
--- a/toolkit/mozapps/extensions/amManager.sys.mjs
+++ b/toolkit/mozapps/extensions/amManager.sys.mjs
@@ -179,16 +179,6 @@ amManager.prototype = {
target.sendAsyncMessage(MSG_ADDON_EVENT, { event, id });
};
let listener = {
- onEnabling: addon => handler("onEnabling", addon.id),
- onEnabled: addon => handler("onEnabled", addon.id),
- onDisabling: addon => handler("onDisabling", addon.id),
- onDisabled: addon => handler("onDisabled", addon.id),
- onInstalling: addon => handler("onInstalling", addon.id),
- onInstalled: addon => handler("onInstalled", addon.id),
- onUninstalling: addon => handler("onUninstalling", addon.id),
- onUninstalled: addon => handler("onUninstalled", addon.id),
- onOperationCancelled: addon =>
- handler("onOperationCancelled", addon.id),
};
this.addonListeners.set(target, listener);
AddonManager.addAddonListener(listener);
diff --git a/toolkit/mozapps/extensions/amWebAPI.sys.mjs b/toolkit/mozapps/extensions/amWebAPI.sys.mjs
index 59d093603a..0c9d9c6176 100644
--- a/toolkit/mozapps/extensions/amWebAPI.sys.mjs
+++ b/toolkit/mozapps/extensions/amWebAPI.sys.mjs
@@ -154,11 +154,9 @@ class Addon extends APIObject {
}
uninstall() {
- return this._apiTask("addonUninstall", [this.id]);
}
setEnabled(value) {
- return this._apiTask("addonSetEnabled", [this.id, value]);
}
}
@@ -210,7 +208,7 @@ export class WebAPI extends APIObject {
getAddonByID(id) {
return this._apiTask("getAddonByID", [id], addonInfo => {
- if (!addonInfo) {
+ if (!addonInfo || addonInfo) {
return null;
}
let addon = new Addon(this.window, this.broker, addonInfo);

View File

@@ -229,11 +229,11 @@ patches:
effect: "Clean new tab page without predetermined site suggestions."
category: "Privacy"
- file: "restrict-mozaddonmanager.patch"
name: "Restrict mozAddonManager"
description: "Prevents addons.mozilla.org from being able to query a list of the user's installed add-ons, and removes its ability to enable and uninstall add-ons."
- file: "install-addons-from-amo-without-mozaddonmanager.patch"
name: "Allow installation of add-ons from the AMO (addons.mozilla.org) without the mozAddonManager API"
description: "Allows users to install add-ons from addons.mozilla.org, without allowing Mozilla to enable, uninstall, and query a list of the user's installed add-ons (via the mozAddonManager API)."
reason: "To prevent fingerprinting and reduce attack surface."
effect: "Allows users to install add-ons from addons.mozilla.org (via the mozAddonManager API), while reducing the amount of information shared with Mozilla and limiting the API's capabilities."
effect: "Users can safely install add-ons from addons.mozilla.org, without compromising privacy and security."
category: "Privacy"
- file: "sanitize-on-exit.patch"