CVE-2026-14101
Overview
Files Changed
content/browser/sandbox_parameters_mac.mmcontent/renderer/sandbox_mac_v2_unittest.mmsandbox/policy/mac/common.sbsandbox/policy/mac/renderer.sb
Patch
From cd96f38a97b7dc0524c55a35d209065ef0be03b8 Mon Sep 17 00:00:00 2001
From: Bryan Oltman <bryanoltman@google.com>
Date: Wed, 20 May 2026 12:17:09 -0700
Subject: [PATCH] [macOS] Deny distributed notifications in the renderer sandbox
Harden the renderer sandbox by denying the ability to post distributed
notifications and looking up the distributed notification service.
This change includes a feature, kMacSandboxDistributedNotifications
(disabled by default), that can be used as a killswitch if needed.
Fixed: 513454805
Change-Id: I82a9c46a2f9e921be7f5b286fdbbb9c2bcc6b643
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7858672
Reviewed-by: Mark Mentovai <mark@chromium.org>
Commit-Queue: Bryan Oltman <bryanoltman@google.com>
Cr-Commit-Position: refs/heads/main@{#1633749}
---
diff --git a/content/browser/sandbox_parameters_mac.mm b/content/browser/sandbox_parameters_mac.mm
index 160a1b4..312394f 100644
--- a/content/browser/sandbox_parameters_mac.mm
+++ b/content/browser/sandbox_parameters_mac.mm
@@ -37,6 +37,11 @@
namespace {
+// If disabled, the macOS sandbox for child processes will deny access to
+// distributed notifications (https://crbug.com/513454805).
+BASE_FEATURE(kMacSandboxDistributedNotifications,
+ base::FEATURE_DISABLED_BY_DEFAULT);
+
std::optional<base::FilePath>& GetNetworkTestCertsDirectory() {
// Set by SetNetworkTestCertsDirectoryForTesting().
static base::NoDestructor<std::optional<base::FilePath>>
@@ -103,6 +108,10 @@
CHECK(serializer->SetBooleanParameter(
sandbox::policy::kParamDisableSandboxDenialLogging, !enable_logging));
+ CHECK(serializer->SetBooleanParameter(
+ sandbox::policy::kParamEnableDistributedNotifications,
+ base::FeatureList::IsEnabled(kMacSandboxDistributedNotifications)));
+
std::string bundle_path =
sandbox::policy::GetCanonicalPath(base::apple::MainBundlePath()).value();
CHECK(
diff --git a/content/renderer/sandbox_mac_v2_unittest.mm b/content/renderer/sandbox_mac_v2_unittest.mm
index c77aa83..4a255cc12 100644
--- a/content/renderer/sandbox_mac_v2_unittest.mm
+++ b/content/renderer/sandbox_mac_v2_unittest.mm
@@ -75,6 +75,9 @@
CHECK(serializer->SetParameter(sandbox::policy::kParamExecutablePath,
executable_path.value()));
+
+ CHECK(serializer->SetBooleanParameter(
+ sandbox::policy::kParamEnableDistributedNotifications, false));
}
} // namespace
diff --git a/sandbox/policy/mac/common.sb b/sandbox/policy/mac/common.sb
index 955c7aa9..a3c02fa 100644
--- a/sandbox/policy/mac/common.sb
+++ b/sandbox/policy/mac/common.sb
@@ -25,6 +25,10 @@
(define darwin-user-dir "DARWIN_USER_DIR")
(define darwin-user-temp-dir "DARWIN_USER_TEMP_DIR")
+; Whether to allow processes to post and look up distributed notifications.
+; See https://crbug.com/513454805.
+(define enable-distributed-notifications "ENABLE_DISTRIBUTED_NOTIFICATIONS")
+
; Sandboxed processes which use Metal may need to disable the shader cache.
(define disable-metal-shader-cache "DISABLE_METAL_SHADER_CACHE")
diff --git a/sandbox/policy/mac/renderer.sb b/sandbox/policy/mac/renderer.sb
index 317a7237..687bca7 100644
--- a/sandbox/policy/mac/renderer.sb
+++ b/sandbox/policy/mac/renderer.sb
@@ -11,6 +11,11 @@
(deny iokit-get-properties process-info* nvram*)
)
+(if (not (param-true? enable-distributed-notifications))
+ (deny distributed-notification-post (with no-log))
+ (deny distributed-notification-post)
+)
+
; Allow cf prefs to work.
(allow user-preference-read)
@@ -75,11 +80,16 @@
; mach IPC
(allow mach-lookup
(global-name "com.apple.cvmsServ") ; https://crbug.com/850021
- (global-name "com.apple.distributed_notifications@Uv3") ; https://crbug.com/792257
(global-name "com.apple.lsd.mapdb")
(global-name "com.apple.system.notification_center") ; https://crbug.com/792217
)
+(if (param-true? enable-distributed-notifications)
+ (allow mach-lookup
+ (global-name "com.apple.distributed_notifications@Uv3")
+ )
+)
+
; IOKit properties.
(allow iokit-get-properties
(iokit-property "CaseSensitive")
Regression Test / PoC
diff --git a/content/renderer/sandbox_mac_v2_unittest.mm b/content/renderer/sandbox_mac_v2_unittest.mm
index c77aa83..4a255cc12 100644
--- a/content/renderer/sandbox_mac_v2_unittest.mm
+++ b/content/renderer/sandbox_mac_v2_unittest.mm
@@ -75,6 +75,9 @@
CHECK(serializer->SetParameter(sandbox::policy::kParamExecutablePath,
executable_path.value()));
+
+ CHECK(serializer->SetBooleanParameter(
+ sandbox::policy::kParamEnableDistributedNotifications, false));
}
} // namespace
Original Bug Report
Potential Spoofing of macOS Distributed Notifications from Renderer Sandbox
Project Fortify, an experimental security project, has identified the following potential security issue. If you’re a feature owner CC-ed on this bug, please do your best to review these reports. Please see https://chromium.googlesource.com/chromium/src/+/main/docs/security/ai-generated-security-bugs-faq.md for more information.
Overview: The macOS renderer sandbox profile lacks an explicit denial for posting distributed notifications, despite allowing access to the notification service. This potentially allows a compromised renderer to spoof system events like screen lock, affecting browser-wide state and privacy timers. This gap in the sandbox could be used for cross-origin denial of service and privacy bypass.
Affected files:
sandbox/policy/mac/renderer.sbcontent/browser/screenlock_monitor/screenlock_monitor_device_source_mac.mmcontent/browser/renderer_host/media/video_capture_manager.ccui/base/idle/idle_mac.mmcontent/browser/theme_helper_mac.mmcomponents/remote_cocoa/app_shim/bridged_content_view.mm
Estimated timestamp from git blame: Unknown (Google3 checkout)
Summary
In the Chromium macOS renderer sandbox profile (sandbox/policy/mac/renderer.sb), the process is granted mach-lookup permission for the distributed notification center service (com.apple.distributed_notifications@Uv3). While this is necessary for the renderer to receive legitimate system broadcasts (such as appearance changes), the sandbox profile does not explicitly deny the distributed-notification-post operation.
Chromium’s macOS sandbox uses version 1 Seatbelt profiles, which are known to permit certain operation classes by default even when a (deny default) rule is present (as referenced in renderer.sb line 8, citing crbug.com/799149). This allows a compromised renderer to use its Mach send-right to the notification daemon (distnoted) to broadcast notifications under any name. The browser process observes several of these notifications and trusts them without origin verification.
Potential Security Impacts
A compromised renderer could potentially trigger the following browser-side handlers by posting spoofed notifications:
-
Cross-Origin Denial of Service (DoS): Spoofing
com.apple.screenIsLockedtriggersVideoCaptureManager::OnScreenLockedin the browser. This method iterates over all active media sessions and terminates all desktop-capture (screen sharing) sessions in all origins globally. -
Privacy Timer Bypass: If a real screen lock occurs, the browser starts an
idle_close_timer_to release camera devices for privacy. A compromised renderer could potentially postcom.apple.screenIsUnlockedto stop this timer, allowing camera devices to remain active while the screen is locked. -
Idle State Manipulation: Notifications like
com.apple.screensaver.didstartandcom.apple.screenIsLockedare observed byui/base/idle/idle_mac.mm. Spoofing these allows a renderer to forge the state returned by theIdleDetectorWeb API and thechrome.idleextension API for all other origins. -
UI/Theme Disruption: Spoofing
AppleAquaScrollBarVariantChangedtriggersThemeHelperMacto broadcast updates to all renderer processes, forcing browser-wide recomputations. Spoofingcom.apple.KeyboardUIModeDidChangeallows a renderer to toggle keyboard-focus traversal behavior for all browser windows.
Potential Steps to Reproduce
Note: These steps are derived from static analysis of the sandbox profiles and browser-side observers; a functional Proof-of-Concept has not yet been executed.
- Gain code execution in a sandboxed renderer process (e.g., via a V8 exploit).
- Obtain a send-right to the
com.apple.distributed_notifications@Uv3Mach service. - Invoke the notification posting interface (e.g., via
notify_postor raw Mach messages) to broadcastcom.apple.screenIsLocked. - In the browser process, observe that active screen sharing sessions in other tabs or origins are terminated.
Suggested Fix
Explicitly deny the distributed-notification-post operation in the renderer’s sandbox profile (sandbox/policy/mac/renderer.sb) and other restricted profiles (e.g., utility.sb). This ensures that sandboxed processes can only observe, and not post, distributed notifications.
(if (param-true? disable-sandbox-denial-logging)
(deny distributed-notification-post (with no-log))
(deny distributed-notification-post)
)
Evaluated with Chrome root at commit: b3153093eb3c78c3e88ccf562bcbc20437a04b0e
Results so far have been promising, but there can be wrong deductions. Feel free to adjust as follows:
- If you are familiar with the severity guidelines, you may adjust the severity.
- If this is a false positive, and there’s no work to be done, please close as WAI.
- If there is work to do here but not a vulnerability, please change the issue type to Task/Bug/FR.
Data from false positives will be used to improve accuracy over time. And please feel free to reach out to me directly if you have concerns or feedback on the project.