Medium firefox Logic Error 🔧 Commit mapped

Overview

Medium
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
Impactmoderate
DescriptionPrivilege escalation in the Enterprise Policies component
ComponentToolkit
Bug ClassLogic Error
Tracker2033850
Fix commit02792816d5db (firefox) +55/-0
CISA KEVNot listed
CreditedMateusz Dobrzyński
Disclosed2026-05-19

Changed Functions

FunctionChangeNotes
if
toolkit/components/enterprisepolicies/EnterprisePoliciesParent.sys.mjs
modified
add_task
toolkit/components/enterprisepolicies/tests/browser/browser_policies_gpo.js
modified
onProfileAfterChange
toolkit/components/enterprisepolicies/tests/browser/browser_policies_gpo.js
modified

Files Changed

  • toolkit/components/enterprisepolicies/EnterprisePoliciesParent.sys.mjs
  • toolkit/components/enterprisepolicies/tests/browser/browser_policies_gpo.js
diff --git a/toolkit/components/enterprisepolicies/EnterprisePoliciesParent.sys.mjs b/toolkit/components/enterprisepolicies/EnterprisePoliciesParent.sys.mjs
index 6afd001e52d..a14ef37411d 100644
--- a/toolkit/components/enterprisepolicies/EnterprisePoliciesParent.sys.mjs
+++ b/toolkit/components/enterprisepolicies/EnterprisePoliciesParent.sys.mjs
@@ -635,6 +635,7 @@ class JSONPoliciesProvider {
 
         if (!this._policies) {
           lazy.log.error("Policies file doesn't contain a 'policies' object");
+          this._policies = null;
           this._failed = true;
         }
       }
diff --git a/toolkit/components/enterprisepolicies/tests/browser/browser_policies_gpo.js b/toolkit/components/enterprisepolicies/tests/browser/browser_policies_gpo.js
index decf158d450..cd419c76061 100644
--- a/toolkit/components/enterprisepolicies/tests/browser/browser_policies_gpo.js
+++ b/toolkit/components/enterprisepolicies/tests/browser/browser_policies_gpo.js
@@ -153,6 +153,60 @@ add_task(async function test_gpo_json_policies() {
   wrk.close();
 });
 
+add_task(async function test_gpo_blank_json_policies() {
+  let { Policies } = ChromeUtils.importESModule(
+    "resource:///modules/policies/Policies.sys.mjs"
+  );
+
+  let gpoPolicyRan = false;
+
+  Policies.gpo_policy = {
+    onProfileAfterChange(manager, param) {
+      is(param, true, "Param matches what was in the registry");
+      gpoPolicyRan = true;
+    },
+  };
+
+  let wrk = Cc["@mozilla.org/windows-registry-key;1"].createInstance(
+    Ci.nsIWindowsRegKey
+  );
+  let regLocation =
+    "SOFTWARE\\Mozilla\\PolicyTesting\\Mozilla\\" + Services.appinfo.name;
+  wrk.create(wrk.ROOT_KEY_CURRENT_USER, regLocation, wrk.ACCESS_WRITE);
+  wrk.writeIntValue("gpo_policy", 1);
+  wrk.close();
+
+  await setupPolicyEngineWithJson(
+    // policies.json missing the "policies" object entirely
+    {},
+
+    // custom schema
+    {
+      properties: {
+        gpo_policy: {
+          type: "boolean",
+        },
+      },
+    }
+  );
+
+  is(
+    Services.policies.status,
+    Ci.nsIEnterprisePolicies.ACTIVE,
+    "Engine is active"
+  );
+
+  ok(gpoPolicyRan, "GPO Policy ran correctly though onProfileAfterChange");
+
+  delete Policies.gpo_policy;
+
+  wrk.open(wrk.ROOT_KEY_CURRENT_USER, "SOFTWARE\\Mozilla", wrk.ACCESS_WRITE);
+  wrk.removeChild("PolicyTesting\\Mozilla\\" + Services.appinfo.name);
+  wrk.removeChild("PolicyTesting\\Mozilla");
+  wrk.removeChild("PolicyTesting");
+  wrk.close();
+});
+
 add_task(async function test_gpo_broken_json_policies() {
   let { Policies } = ChromeUtils.importESModule(
     "resource:///modules/policies/Policies.sys.mjs"
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/toolkit/components/enterprisepolicies/tests/browser/browser_policies_gpo.js b/toolkit/components/enterprisepolicies/tests/browser/browser_policies_gpo.js
index decf158d450..cd419c76061 100644
--- a/toolkit/components/enterprisepolicies/tests/browser/browser_policies_gpo.js
+++ b/toolkit/components/enterprisepolicies/tests/browser/browser_policies_gpo.js
@@ -153,6 +153,60 @@ add_task(async function test_gpo_json_policies() {
   wrk.close();
 });
 
+add_task(async function test_gpo_blank_json_policies() {
+  let { Policies } = ChromeUtils.importESModule(
+    "resource:///modules/policies/Policies.sys.mjs"
+  );
+
+  let gpoPolicyRan = false;
+
+  Policies.gpo_policy = {
+    onProfileAfterChange(manager, param) {
+      is(param, true, "Param matches what was in the registry");
+      gpoPolicyRan = true;
+    },
+  };
+
+  let wrk = Cc["@mozilla.org/windows-registry-key;1"].createInstance(
+    Ci.nsIWindowsRegKey
+  );
+  let regLocation =
+    "SOFTWARE\\Mozilla\\PolicyTesting\\Mozilla\\" + Services.appinfo.name;
+  wrk.create(wrk.ROOT_KEY_CURRENT_USER, regLocation, wrk.ACCESS_WRITE);
+  wrk.writeIntValue("gpo_policy", 1);
+  wrk.close();
+
+  await setupPolicyEngineWithJson(
+    // policies.json missing the "policies" object entirely
+    {},
+
+    // custom schema
+    {
+      properties: {
+        gpo_policy: {
+          type: "boolean",
+        },
+      },
+    }
+  );
+
+  is(
+    Services.policies.status,
+    Ci.nsIEnterprisePolicies.ACTIVE,
+    "Engine is active"
+  );
+
+  ok(gpoPolicyRan, "GPO Policy ran correctly though onProfileAfterChange");
+
+  delete Policies.gpo_policy;
+
+  wrk.open(wrk.ROOT_KEY_CURRENT_USER, "SOFTWARE\\Mozilla", wrk.ACCESS_WRITE);
+  wrk.removeChild("PolicyTesting\\Mozilla\\" + Services.appinfo.name);
+  wrk.removeChild("PolicyTesting\\Mozilla");
+  wrk.removeChild("PolicyTesting");
+  wrk.close();
+});
+
 add_task(async function test_gpo_broken_json_policies() {
   let { Policies } = ChromeUtils.importESModule(
     "resource:///modules/policies/Policies.sys.mjs"
Loading diff…