CVE-2026-17916
Overview
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifchrome/browser/ui/webui/settings/on_device_ai_settings_handler.cc |
modified |
Files Changed
chrome/browser/ui/webui/settings/on_device_ai_settings_handler.ccchrome/browser/ui/webui/settings/on_device_ai_settings_handler_unittest.cc
Patch
From 6f95af316f364ac95e3711c6fcd648511a387e91 Mon Sep 17 00:00:00 2001
From: Jingyun Liu <jingyun@google.com>
Date: Mon, 08 Jun 2026 18:33:24 -0700
Subject: [PATCH] Disallow enabling On-Device AI if disallowed by enterprise policy
- The UI already greys out the toggle when enterprise policy disabled
- Adding extra checks in the browser code to prevent vulnerbility
Bug: 510808598
Change-Id: I93ce55d627006087f0887af9bf801624345a2845
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7902696
Auto-Submit: Jingyun Liu <jingyun@google.com>
Reviewed-by: Mike Wasserman <msw@chromium.org>
Commit-Queue: Mike Wasserman <msw@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1643598}
---
diff --git a/chrome/browser/ui/webui/settings/on_device_ai_settings_handler.cc b/chrome/browser/ui/webui/settings/on_device_ai_settings_handler.cc
index ed6b0b07..8242111 100644
--- a/chrome/browser/ui/webui/settings/on_device_ai_settings_handler.cc
+++ b/chrome/browser/ui/webui/settings/on_device_ai_settings_handler.cc
@@ -89,9 +89,22 @@
void OnDeviceAiSettingsHandler::HandleSetOnDeviceAiEnabled(
const base::ListValue& args) {
CHECK_EQ(1U, args.size());
+
+ PrefService* local_state = g_browser_process->local_state();
+ using optimization_guide::model_execution::prefs::
+ GenAILocalFoundationalModelEnterprisePolicySettings;
+ bool disallowed_by_policy =
+ optimization_guide::
+ GetGenAILocalFoundationalModelEnterprisePolicySettings(local_state) ==
+ GenAILocalFoundationalModelEnterprisePolicySettings::kDisallowed;
+ if (disallowed_by_policy) {
+ LOG(ERROR) << "Cannot set on-device AI user setting when disallowed "
+ "by policy.";
+ return;
+ }
+
bool enabled = args[0].GetBool();
- g_browser_process->local_state()->SetBoolean(kOnDeviceAiUserSettingsEnabled,
- enabled);
+ local_state->SetBoolean(kOnDeviceAiUserSettingsEnabled, enabled);
}
void OnDeviceAiSettingsHandler::HandleOpenFeedbackDialog(
diff --git a/chrome/browser/ui/webui/settings/on_device_ai_settings_handler_unittest.cc b/chrome/browser/ui/webui/settings/on_device_ai_settings_handler_unittest.cc
index dc4cc94..03c191f 100644
--- a/chrome/browser/ui/webui/settings/on_device_ai_settings_handler_unittest.cc
+++ b/chrome/browser/ui/webui/settings/on_device_ai_settings_handler_unittest.cc
@@ -77,6 +77,27 @@
}
TEST_F(OnDeviceAiSettingsHandlerTest,
+ HandleSetOnDeviceAiEnabled_PolicyDisabled) {
+ // Ensure the pref is initially false for this test.
+ local_state()->SetBoolean(kOnDeviceAiUserSettingsEnabled, false);
+
+ using optimization_guide::model_execution::prefs::
+ GenAILocalFoundationalModelEnterprisePolicySettings;
+ local_state()->SetInteger(
+ optimization_guide::model_execution::prefs::localstate::
+ kGenAILocalFoundationalModelEnterprisePolicySettings,
+ static_cast<int>(
+ GenAILocalFoundationalModelEnterprisePolicySettings::kDisallowed));
+
+ base::ListValue args;
+ args.Append(true);
+ handler()->HandleSetOnDeviceAiEnabled(args);
+
+ EXPECT_FALSE(local_state()->GetBoolean(kOnDeviceAiUserSettingsEnabled));
+}
+
+
+TEST_F(OnDeviceAiSettingsHandlerTest,
HandleGetOnDeviceAiEnabled_PolicyDisabled) {
using optimization_guide::model_execution::prefs::
GenAILocalFoundationalModelEnterprisePolicySettings;
Regression Test / PoC
diff --git a/chrome/browser/ui/webui/settings/on_device_ai_settings_handler_unittest.cc b/chrome/browser/ui/webui/settings/on_device_ai_settings_handler_unittest.cc
index dc4cc94..03c191f 100644
--- a/chrome/browser/ui/webui/settings/on_device_ai_settings_handler_unittest.cc
+++ b/chrome/browser/ui/webui/settings/on_device_ai_settings_handler_unittest.cc
@@ -77,6 +77,27 @@
}
TEST_F(OnDeviceAiSettingsHandlerTest,
+ HandleSetOnDeviceAiEnabled_PolicyDisabled) {
+ // Ensure the pref is initially false for this test.
+ local_state()->SetBoolean(kOnDeviceAiUserSettingsEnabled, false);
+
+ using optimization_guide::model_execution::prefs::
+ GenAILocalFoundationalModelEnterprisePolicySettings;
+ local_state()->SetInteger(
+ optimization_guide::model_execution::prefs::localstate::
+ kGenAILocalFoundationalModelEnterprisePolicySettings,
+ static_cast<int>(
+ GenAILocalFoundationalModelEnterprisePolicySettings::kDisallowed));
+
+ base::ListValue args;
+ args.Append(true);
+ handler()->HandleSetOnDeviceAiEnabled(args);
+
+ EXPECT_FALSE(local_state()->GetBoolean(kOnDeviceAiUserSettingsEnabled));
+}
+
+
+TEST_F(OnDeviceAiSettingsHandlerTest,
HandleGetOnDeviceAiEnabled_PolicyDisabled) {
using optimization_guide::model_execution::prefs::
GenAILocalFoundationalModelEnterprisePolicySettings;
Original Bug Report
OnDeviceAiSettingsHandler mutates on-device AI user setting despite mandatory GenAILocalFoundationalModelSettings=Disabled and hidden AI settings UI
Report description
OnDeviceAiSettingsHandler mutates on-device AI user setting despite mandatory GenAILocalFoundationalModelSettings=Disabled and hidden AI settings UI
Bug location
Where do you want to report your vulnerability?
Chrome VRP – Report security issues affecting the Chrome browser. See program rules
Which URL (or repository) have you found the vulnerability in?
The problem
Please describe the technical details of the vulnerability
Chrome registers the OnDeviceAiSettingsHandler on chrome://settings even when the AI settings UI is unavailable and a mandatory enterprise policy disables local foundational GenAI model usage.
Environment tested:
- Chrome 147.0.7727.138 (Official Build) (arm64)
- chrome://policy shows:
- GenAILocalFoundationalModelSettings = 1
- Source: Platform
- Applies to: Machine
- Level: Mandatory
- Status: OK
Observed UI/policy state:
- Navigating to chrome://settings/ai redirects to chrome://settings.
- In chrome://settings, loadTimeData values showAiPage and showOnDeviceAiSettings are missing.
- chrome://on-device-internals shows:
- enabled by enterprise policy: false
- foundational model state: Not Eligible
Despite this, chrome://settings still exposes the legacy WebUI message handler for on-device AI settings. Calling getOnDeviceAiEnabled returns allowedByPolicy:false, but setOnDeviceAiEnabled still mutates the user setting.
Relevant source:
- chrome/browser/ui/webui/settings/on_device_ai_settings_handler.cc registers:
- getOnDeviceAiEnabled
- setOnDeviceAiEnabled
- openOnDeviceAiFeedbackDialog
- GetOnDeviceAiState() computes allowedByPolicy from GenAILocalFoundationalModelEnterprisePolicySettings.
- HandleSetOnDeviceAiEnabled() does not check allowedByPolicy or enterprise policy state. It directly writes: optimization_guide.on_device_foundational_model_user_settings
Proof of concept from chrome://settings DevTools console:
(async () => {
function getOnDeviceAiEnabled() {
return new Promise((resolve) => {
const callbackId = vrp_get_${Date.now()}_${Math.random()};
const original = cr.webUIResponse;
const timer = setTimeout(() => {
cr.webUIResponse = original;
resolve({responded:false,error:’timeout’});
}, 3000);
cr.webUIResponse = function(id, success, response) {
if (id !== callbackId) return original.apply(this, arguments);
clearTimeout(timer);
cr.webUIResponse = original;
resolve({responded:true,success,response});
};
chrome.send('getOnDeviceAiEnabled', [callbackId]);
});
}
const before = await getOnDeviceAiEnabled(); chrome.send(‘setOnDeviceAiEnabled’, [false]); const afterFalse = await getOnDeviceAiEnabled(); chrome.send(‘setOnDeviceAiEnabled’, [true]); const afterTrue = await getOnDeviceAiEnabled();
console.log(JSON.stringify({before, afterFalse, afterTrue}, null, 2)); })();
Observed result:
{ “before”: { “responded”: true, “success”: true, “response”: { “allowedByPolicy”: false, “enabled”: true } }, “afterFalse”: { “responded”: true, “success”: true, “response”: { “allowedByPolicy”: false, “enabled”: false } }, “afterTrue”: { “responded”: true, “success”: true, “response”: { “allowedByPolicy”: false, “enabled”: true } } }
The mutation persisted after browser restart. chrome://on-device-internals also reflected the mutation: “enabled by user setting” changed false/true while “enabled by enterprise policy” stayed false.
Security impact: A hidden WebUI handler allows a user-level on-device AI setting to be modified under a mandatory machine-level policy that disables local foundational GenAI model usage. The normal AI settings UI is not available, but the backend WebUI message remains callable and mutates persistent local state.
Limitation: I did not prove that the model can be downloaded or executed despite policy. chrome://on-device-internals continued to show the foundational model as Not Eligible because enabled by enterprise policy remained false.
Impact analysis
The demonstrated exploit path requires script execution in the privileged chrome://settings WebUI context, for example through DevTools or another bug that can execute JavaScript in that WebUI. I tested a normal Chrome extension attacker model using chrome.scripting.executeScript against chrome://settings, and Chrome blocked it with “Cannot access a chrome:// URL.”
An attacker with code execution in chrome://settings can call the hidden OnDeviceAiSettingsHandler and mutate the persistent on-device AI user setting even while a mandatory machine-level GenAILocalFoundationalModelSettings policy disables local foundational GenAI model usage and the normal AI settings UI is hidden.
What the attacker gains:
- Ability to change optimization_guide.on_device_foundational_model_user_settings despite allowedByPolicy:false.
- The changed value persists after browser restart.
- chrome://on-device-internals reflects the mutation as “enabled by user setting: true/false.”
Current limitation: I did not demonstrate model download or model execution despite the enterprise policy. The model remained Not Eligible because “enabled by enterprise policy” stayed false. Therefore the current impact is policy-inconsistent persistent state mutation of a hidden/policy-disabled setting, not a confirmed full bypass of model execution.
The cause
What version of Chrome have you found the security issue in?
147.0.7727.138 (Official Build) (arm64)
Is the security issue related to a crash?
No, it is not related to a crash.
Choose the type of vulnerability
Permissions Bypass
How would you like to be publicly acknowledged for your report?
Itzik Chimino