Files
lbmk/config/firefox/default/patches/0031-rs-blocker.patch.patch
T
Leah Rowe 2b34aeea5d WIP: convert to lwmk
Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-09-08 06:44:40 +01:00

313 lines
11 KiB
Diff

From 38c03c5e125329cc45f3b290ae16f50fe533a5c3 Mon Sep 17 00:00:00 2001
From: LibreWolf Developers <noreply@librewolf.net>
Date: Sun, 6 Sep 2026 10:11:17 +0100
Subject: [PATCH 31/52] rs-blocker.patch
---
services/settings/RemoteSettings.worker.mjs | 8 +-
.../settings/RemoteSettingsClient.sys.mjs | 21 ++++-
.../settings/RemoteSettingsWorker.sys.mjs | 4 +-
services/settings/SharedUtils.sys.mjs | 78 ++++++++++++++++++-
services/settings/Utils.sys.mjs | 28 ++++++-
services/settings/remote-settings.sys.mjs | 5 ++
.../search/SearchEngineSelector.sys.mjs | 8 +-
7 files changed, 136 insertions(+), 16 deletions(-)
diff --git a/services/settings/RemoteSettings.worker.mjs b/services/settings/RemoteSettings.worker.mjs
index 3e4e915c13ed..a92768553a29 100644
--- a/services/settings/RemoteSettings.worker.mjs
+++ b/services/settings/RemoteSettings.worker.mjs
@@ -62,12 +62,16 @@ const Agent = {
*
* @param {string} bucket
* @param {string} collection
+ * @param {string} allowedCollections
+ * @param {string} allowedCollectionsFromDump
* @returns {int} Number of records loaded from dump or -1 if no dump found.
*/
- async importJSONDump(bucket, collection) {
+ async importJSONDump(bucket, collection, allowedCollections, allowedCollectionsFromDump) {
const { data: records, timestamp } = await SharedUtils.loadJSONDump(
bucket,
- collection
+ collection,
+ allowedCollections,
+ allowedCollectionsFromDump
);
if (records === null) {
// Return -1 if file is missing.
diff --git a/services/settings/RemoteSettingsClient.sys.mjs b/services/settings/RemoteSettingsClient.sys.mjs
index f4f9b1c0bce9..fc3c6bb2b1ba 100644
--- a/services/settings/RemoteSettingsClient.sys.mjs
+++ b/services/settings/RemoteSettingsClient.sys.mjs
@@ -209,12 +209,21 @@ class AttachmentDownloader extends Downloader {
return cacheImpl;
}
+ get identifier() {
+ return this._client.identifier;
+ }
+
/**
* Download attachment and report Telemetry on failure.
*
* @see Downloader.download
*/
async download(record, options) {
+ if (!lazy.SharedUtils.isCollectionAllowed(this.bucketName, this.collectionName, lazy.Utils.allowedCollections)) {
+ throw Error(
+ `Download attempt to RS collection "${this.identifier}" was blocked.`
+ );
+ }
await lazy.UptakeTelemetry.report(
lazy.UptakeTelemetry.STATUS.DOWNLOAD_START,
{
@@ -586,7 +595,9 @@ export class RemoteSettingsClient extends EventEmitter {
}
({ data } = await lazy.SharedUtils.loadJSONDump(
this.bucketName,
- this.collectionName
+ this.collectionName,
+ lazy.Utils.allowedCollections,
+ lazy.Utils.allowedCollectionsFromDump
));
if (data !== null) {
lazy.console.info(`${this.identifier} falling back to JSON dump`);
@@ -656,6 +667,10 @@ export class RemoteSettingsClient extends EventEmitter {
return;
}
+ if (!lazy.SharedUtils.isCollectionAllowed(this.bucketName, this.collectionName, lazy.Utils.allowedCollections)) {
+ return;
+ }
+
// We want to know which timestamp we are expected to obtain in order to leverage
// cache busting. We don't provide ETag because we don't want a 304.
const { changes } = await lazy.Utils.fetchLatestChanges(
@@ -1040,7 +1055,9 @@ export class RemoteSettingsClient extends EventEmitter {
lazy.console.info(`${this.identifier} try to restore dump`);
const result = await lazy.RemoteSettingsWorker.importJSONDump(
this.bucketName,
- this.collectionName
+ this.collectionName,
+ lazy.Utils.allowedCollections,
+ lazy.Utils.allowedCollectionsFromDump
);
if (result < 0) {
lazy.console.debug(`${this.identifier} no dump available`);
diff --git a/services/settings/RemoteSettingsWorker.sys.mjs b/services/settings/RemoteSettingsWorker.sys.mjs
index 57bfb3f3d544..874b35abff18 100644
--- a/services/settings/RemoteSettingsWorker.sys.mjs
+++ b/services/settings/RemoteSettingsWorker.sys.mjs
@@ -162,8 +162,8 @@ class Worker {
]);
}
- async importJSONDump(bucket, collection) {
- return this._execute("importJSONDump", [bucket, collection], {
+ async importJSONDump(bucket, collection, allowedCollections, allowedCollectionsFromDump) {
+ return this._execute("importJSONDump", [bucket, collection, allowedCollections, allowedCollectionsFromDump], {
mustComplete: true,
});
}
diff --git a/services/settings/SharedUtils.sys.mjs b/services/settings/SharedUtils.sys.mjs
index e5b20d9b9dd6..9a71c99668f0 100644
--- a/services/settings/SharedUtils.sys.mjs
+++ b/services/settings/SharedUtils.sys.mjs
@@ -34,8 +34,13 @@ export var SharedUtils = {
*
* @param {string} bucket
* @param {string} collection
+ * @param {string} allowedCollections
+ * @param {string} allowedCollectionsFromDump
*/
- async loadJSONDump(bucket, collection) {
+ async loadJSONDump(bucket, collection, allowedCollections, allowedCollectionsFromDump) {
+ if (!this.isCollectionAllowedFromDump(bucket, collection, allowedCollections, allowedCollectionsFromDump)) {
+ return { data: null, timestamp: null };
+ }
// When using the preview bucket, we still want to load the main dump.
// But we store it locally in the preview bucket.
const jsonBucket = bucket.replace("-preview", "");
@@ -50,4 +55,75 @@ export var SharedUtils = {
// Will throw if JSON is invalid.
return response.json();
},
+
+ /**
+ * Internal code to determine whether the bucket and collection are allowed to
+ * be loaded by the remote settings client for a given list of allowed
+ * bucket/collection combinations.
+ * @param {string} bucket
+ * @param {string} collection
+ * @param {Array<string>} allowedCollections
+ * @returns {boolean} whether the bucket and collection are allowed to load
+ */
+ _isCollectionAllowedInternal(bucket, collection, allowedCollections) {
+ return (
+ allowedCollections.includes(`${bucket}/${collection}`) ||
+ allowedCollections.includes(`${bucket}/*`) ||
+ allowedCollections.includes("*")
+ );
+ },
+
+ /**
+ * Determines whether the bucket and collection are allowed to be loaded by the
+ * remote settings client.
+ * @param {string} bucket
+ * @param {string} collection
+ * @param {string} allowedCollections
+ * @returns {boolean} whether the bucket and collection are allowed to load
+ */
+ isCollectionAllowed(bucket, collection, allowedCollections) {
+ if (
+ this._isCollectionAllowedInternal(
+ bucket,
+ collection,
+ allowedCollections
+ )
+ ) {
+ return true;
+ }
+ console.warn(
+ `Connection attempt to RS collection "${bucket}/${collection}" was blocked/filtered.`
+ );
+ return false;
+ },
+
+ /**
+ * Determines whether the bucket and collection are allowed to be loaded from
+ * an in-tree remote settings dump.
+ * @param {string} bucket
+ * @param {string} collection
+ * @param {string} allowedCollections
+ * @param {string} allowedCollectionsFromDump
+ * @returns {boolean} whether the bucket and collection are allowed to load
+ */
+ isCollectionAllowedFromDump(bucket, collection, allowedCollections, allowedCollectionsFromDump) {
+ if (
+ this._isCollectionAllowedInternal(
+ bucket,
+ collection,
+ allowedCollectionsFromDump
+ ) ||
+ this._isCollectionAllowedInternal(
+ bucket,
+ collection,
+ allowedCollections
+ )
+ ) {
+ return true;
+ }
+ console.warn(
+ `Access attempt to RS collection "${bucket}/${collection}" from local dump was blocked/filtered.`
+ );
+ return false;
+ },
};
diff --git a/services/settings/Utils.sys.mjs b/services/settings/Utils.sys.mjs
index 40e919a997a5..ccc7694bcc28 100644
--- a/services/settings/Utils.sys.mjs
+++ b/services/settings/Utils.sys.mjs
@@ -99,6 +99,18 @@ XPCOMUtils.defineLazyPreferenceGetter(
""
);
+ChromeUtils.defineLazyGetter(lazy, "allowedCollections", () =>
+ Services.prefs
+ .getStringPref("librewolf.services.settings.allowedCollections", "")
+ .split(",")
+);
+
+ChromeUtils.defineLazyGetter(lazy, "allowedCollectionsFromDump", () =>
+ Services.prefs
+ .getStringPref("librewolf.services.settings.allowedCollectionsFromDump", "")
+ .split(",")
+);
+
function _isUndefined(value) {
return typeof value === "undefined";
}
@@ -111,6 +123,14 @@ export var Utils = {
: AppConstants.REMOTE_SETTINGS_SERVER_URLS[0];
},
+ get allowedCollections() {
+ return lazy.allowedCollections;
+ },
+
+ get allowedCollectionsFromDump() {
+ return lazy.allowedCollectionsFromDump;
+ },
+
CHANGES_PATH: "/buckets/monitor/collections/changes/changeset",
/**
@@ -451,7 +471,9 @@ export var Utils = {
if (lastModified === undefined) {
const { timestamp: dumpTimestamp } = await lazy.SharedUtils.loadJSONDump(
bucket,
- collection
+ collection,
+ this.allowedCollections,
+ this.allowedCollectionsFromDump
);
// Client recognize -1 as missing dump.
lastModified = dumpTimestamp ?? -1;
@@ -561,7 +583,9 @@ export var Utils = {
}
return {
- changes,
+ changes: changes.filter(change =>
+ lazy.SharedUtils.isCollectionAllowed(change.bucket, change.collection, this.allowedCollections)
+ ),
timestamp,
serverTimeMillis,
backoffSeconds,
diff --git a/services/settings/remote-settings.sys.mjs b/services/settings/remote-settings.sys.mjs
index b180cfc850ee..c8db18344c1f 100644
--- a/services/settings/remote-settings.sys.mjs
+++ b/services/settings/remote-settings.sys.mjs
@@ -16,6 +16,7 @@ ChromeUtils.defineESModuleGetters(lazy, {
pushBroadcastService: "resource://gre/modules/PushBroadcastService.sys.mjs",
RemoteSettingsClient:
"resource://services-settings/RemoteSettingsClient.sys.mjs",
+ SharedUtils: "resource://services-settings/SharedUtils.sys.mjs",
SyncHistory: "resource://services-settings/SyncHistory.sys.mjs",
UptakeTelemetry: "resource://services-settings/UptakeTelemetry.sys.mjs",
Utils: "resource://services-settings/Utils.sys.mjs",
@@ -286,6 +287,10 @@ function remoteSettingsFunction() {
const collection = changeset.metadata.id;
const identifier = `${bucket}/${collection}`;
+ if (!lazy.SharedUtils.isCollectionAllowed(bucket, collection, lazy.Utils.allowedCollections)) {
+ continue;
+ }
+
if (pulled.includes(identifier)) {
// The startup bundles contain both main and preview changesets.
// Importing both increases complexity down the line, and brings no value.
diff --git a/toolkit/components/search/SearchEngineSelector.sys.mjs b/toolkit/components/search/SearchEngineSelector.sys.mjs
index 3a42b383af19..3befe8d89988 100644
--- a/toolkit/components/search/SearchEngineSelector.sys.mjs
+++ b/toolkit/components/search/SearchEngineSelector.sys.mjs
@@ -409,13 +409,7 @@ export class SearchEngineSelector {
* could be obtained.
*/
async #getConfigurationOverrides() {
- let result = [];
- try {
- result = await this.#remoteConfigOverrides.get();
- } catch (ex) {
- // This data is remote only, so we just return an empty array if it fails.
- }
- return result;
+ return [];
}
/**
--
2.47.3