File rs-blocker.patch of Package LibreWolf

diff --git a/services/settings/RemoteSettingsClient.sys.mjs b/services/settings/RemoteSettingsClient.sys.mjs
index fc7f6705da46..a3fdd04f03bc 100644
--- a/services/settings/RemoteSettingsClient.sys.mjs
+++ b/services/settings/RemoteSettingsClient.sys.mjs
@@ -228,6 +228,11 @@ class AttachmentDownloader extends Downloader {
    * @see Downloader.download
    */
   async download(record, options) {
+    if (!lazy.Utils.isCollectionAllowed(this.bucketName, this.collectionName)) {
+      throw Error(
+        `Download attempt to RS collection "${this.identifier}" was blocked.`
+      );
+    }
     await lazy.UptakeTelemetry.report(
       TELEMETRY_COMPONENT,
       lazy.UptakeTelemetry.STATUS.DOWNLOAD_START,
@@ -652,6 +657,10 @@ export class RemoteSettingsClient extends EventEmitter {
       return;
     }
 
+    if (!lazy.Utils.isCollectionAllowed(this.bucketName, this.collectionName)) {
+      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(
@@ -1031,6 +1040,14 @@ export class RemoteSettingsClient extends EventEmitter {
    * Import the JSON files from services/settings/dump into the local DB.
    */
   async _importJSONDump() {
+    if (
+      !lazy.Utils.isCollectionAllowedFromDump(
+        this.bucketName,
+        this.collectionName
+      )
+    ) {
+      return 0;
+    }
     lazy.console.info(`${this.identifier} try to restore dump`);
     const result = await lazy.RemoteSettingsWorker.importJSONDump(
       this.bucketName,
diff --git a/services/settings/Utils.sys.mjs b/services/settings/Utils.sys.mjs
index cbdf07bcdae1..4e923ff44f33 100644
--- a/services/settings/Utils.sys.mjs
+++ b/services/settings/Utils.sys.mjs
@@ -75,6 +75,18 @@ ChromeUtils.defineLazyGetter(lazy, "allowServerURLOverride", () => {
   return false;
 });
 
+ChromeUtils.defineLazyGetter(lazy, "allowedCollections", () =>
+  Services.prefs
+    .getStringPref("librewolf.services.settings.allowedCollections", "")
+    .split(",")
+);
+
+ChromeUtils.defineLazyGetter(lazy, "allowedCollectionsFromDump", () =>
+  Services.prefs
+    .getStringPref("librewolf.services.settings.allowedCollectionsFromDump", "")
+    .split(",")
+);
+
 XPCOMUtils.defineLazyPreferenceGetter(
   lazy,
   "gServerURL",
@@ -205,12 +217,80 @@ export var Utils = {
     return false;
   },
 
+  /**
+   * 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) {
+    bucket = this.actualBucketName(bucket);
+    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
+   * @returns {boolean} whether the bucket and collection are allowed to load
+   */
+  isCollectionAllowed(bucket, collection) {
+    if (
+      this._isCollectionAllowedInternal(
+        bucket,
+        collection,
+        lazy.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
+   * @returns {boolean} whether the bucket and collection are allowed to load
+   */
+  isCollectionAllowedFromDump(bucket, collection) {
+    if (
+      this._isCollectionAllowedInternal(
+        bucket,
+        collection,
+        lazy.allowedCollectionsFromDump
+      ) ||
+      this._isCollectionAllowedInternal(
+        bucket,
+        collection,
+        lazy.allowedCollections
+      )
+    ) {
+      return true;
+    }
+    console.warn(
+      `Access attempt to RS collection "${bucket}/${collection}" from local dump was blocked/filtered.`
+    );
+    return false;
+  },
+
   /**
    * A wrapper around `ServiceRequest` that behaves like `fetch()`.
    *
    * Use this in order to leverage the `beConservative` flag, for
    * example to avoid using HTTP3 to fetch critical data.
-   *
    * @param input a resource
    * @param init request options
    * @returns a Response object
@@ -483,7 +563,9 @@ export var Utils = {
     }
 
     return {
-      changes,
+      changes: changes.filter(change =>
+        this.isCollectionAllowed(change.bucket, change.collection)
+      ),
       currentEtag: `"${timestamp}"`,
       serverTimeMillis,
       backoffSeconds,
openSUSE Build Service is sponsored by