CVE-2026-11233
Overview
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifcontent/browser/devtools/protocol/emulation_handler.cc |
modified | |
GetDevicePostureProvidercontent/browser/renderer_host/render_widget_host_delegate.cc |
modified | |
RenderFrameProxyHostcontent/browser/renderer_host/render_widget_host_delegate.h |
modified | |
RenderWidgetHostImplcontent/browser/renderer_host/render_widget_host_delegate.h |
modified | |
DevicePostureProviderImplcontent/browser/renderer_host/render_widget_host_delegate.h |
modified | |
RenderWidgetHostViewBasecontent/browser/renderer_host/render_widget_host_delegate.h |
modified | |
RenderViewHostDelegateViewcontent/browser/renderer_host/render_widget_host_delegate.h |
modified | |
TextInputManagercontent/browser/renderer_host/render_widget_host_delegate.h |
modified | |
GetDevicePostureProvidercontent/browser/web_contents/web_contents_impl.cc |
modified |
Files Changed
content/browser/device_posture/device_posture_provider_impl.hcontent/browser/devtools/protocol/emulation_handler.cccontent/browser/renderer_host/render_widget_host_delegate.cccontent/browser/renderer_host/render_widget_host_delegate.hcontent/browser/web_contents/web_contents_impl.cccontent/browser/web_contents/web_contents_impl.hthird_party/blink/public/mojom/device_posture/device_posture_provider.mojomthird_party/blink/renderer/core/frame/local_frame.ccthird_party/blink/renderer/core/frame/local_frame.hthird_party/blink/renderer/core/frame/local_frame_mojo_handler.ccthird_party/blink/renderer/core/frame/local_frame_mojo_handler.h
Patch
From 829bf4ec033ca45078c880a193c73fa6c534c37c Mon Sep 17 00:00:00 2001 From: Menard, Alexis <[email protected]> Date: Thu, 16 Apr 2026 17:16:22 -0700 Subject: [PATCH] device-posture: Remove posture override mechanism from mojo. These interfaces were used by devtools/emulation through WPT to override the device posture for testing purposes rather than relying on actual device posture. We can rework this by keeping the overriding mechanism in content/browser only. Bug: 496095145, 496088449 Change-Id: Ia27f971ea434c5e2328290ea7286b66f6cf6819b Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7763896 Reviewed-by: Bo Liu <[email protected]> Commit-Queue: Menard, Alexis <[email protected]> Reviewed-by: Reilly Grant <[email protected]> Reviewed-by: Dominic Farolino <[email protected]> Cr-Commit-Position: refs/heads/main@{#1616212} --- diff --git a/content/browser/device_posture/device_posture_provider_impl.h b/content/browser/device_posture/device_posture_provider_impl.h index f4821ed..ce621efe 100644 --- a/content/browser/device_posture/device_posture_provider_impl.h +++ b/content/browser/device_posture/device_posture_provider_impl.h @@ -32,10 +32,9 @@ mojo::PendingReceiver<blink::mojom::DevicePostureProvider> receiver); DevicePosturePlatformProvider* platform_provider() const; - // DevicePostureProvider implementation. CONTENT_EXPORT void OverrideDevicePostureForEmulation( - blink::mojom::DevicePostureType posture) override; - CONTENT_EXPORT void DisableDevicePostureOverrideForEmulation() override; + blink::mojom::DevicePostureType posture); + CONTENT_EXPORT void DisableDevicePostureOverrideForEmulation(); private: // DevicePostureClient implementation. diff --git a/content/browser/devtools/protocol/emulation_handler.cc b/content/browser/devtools/protocol/emulation_handler.cc index d5d449a..276cf99 100644 --- a/content/browser/devtools/protocol/emulation_handler.cc +++ b/content/browser/devtools/protocol/emulation_handler.cc @@ -779,6 +779,7 @@ if (device_posture) { params.device_posture = DevicePostureTypeFromString(device_posture->GetType()).value(); + SetDevicePostureOverride(std::move(device_posture)); } if (mobile || @@ -851,6 +852,7 @@ return Response::Success(); GetWebContents()->ClearDeviceEmulationSize(); + ClearDevicePostureOverride(); device_emulation_enabled_ = false; device_emulation_params_ = blink::DeviceEmulationParams(); if (screen_orientation_lock_emulation_enabled_) { diff --git a/content/browser/renderer_host/render_widget_host_delegate.cc b/content/browser/renderer_host/render_widget_host_delegate.cc index 0311764..f180bdd 100644 --- a/content/browser/renderer_host/render_widget_host_delegate.cc +++ b/content/browser/renderer_host/render_widget_host_delegate.cc @@ -102,7 +102,7 @@ return ui::mojom::WindowShowState::kDefault; } -blink::mojom::DevicePostureProvider* +DevicePostureProviderImpl* RenderWidgetHostDelegate::GetDevicePostureProvider() { return nullptr; } diff --git a/content/browser/renderer_host/render_widget_host_delegate.h b/content/browser/renderer_host/render_widget_host_delegate.h index 4dad6bba..e4c41fea 100644 --- a/content/browser/renderer_host/render_widget_host_delegate.h +++ b/content/browser/renderer_host/render_widget_host_delegate.h @@ -20,7 +20,6 @@ #include "services/metrics/public/cpp/ukm_recorder.h" #include "third_party/blink/public/common/input/web_input_event.h" #include "third_party/blink/public/common/page/drag_operation.h" -#include "third_party/blink/public/mojom/device_posture/device_posture_provider.mojom.h" #include "third_party/blink/public/mojom/frame/lifecycle.mojom.h" #include "third_party/blink/public/mojom/input/input_handler.mojom-shared.h" #include "third_party/blink/public/mojom/manifest/display_mode.mojom.h" @@ -56,6 +55,7 @@ class RenderFrameProxyHost; class RenderWidgetHostImpl; +class DevicePostureProviderImpl; class RenderWidgetHostViewBase; class RenderViewHostDelegateView; class TextInputManager; @@ -238,7 +238,7 @@ virtual ui::mojom::WindowShowState GetWindowShowState(); // Returns the device posture provider tracking the device posture. - virtual blink::mojom::DevicePostureProvider* GetDevicePostureProvider(); + virtual DevicePostureProviderImpl* GetDevicePostureProvider(); // Returns whether the window can be resized or not. Defaults to true for // desktopOSs and false for mobileOSs. diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index ff27b82..b3480792 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc @@ -4939,8 +4939,7 @@ : ui::mojom::WindowShowState::kDefault; } -blink::mojom::DevicePostureProvider* -WebContentsImpl::GetDevicePostureProvider() { +DevicePostureProviderImpl* WebContentsImpl::GetDevicePostureProvider() { return DevicePostureProviderImpl::GetOrCreate(this); } diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index 757277f..368b9d4c 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h @@ -1185,7 +1185,7 @@ // bool IsFullscreen() const override; blink::mojom::DisplayMode GetDisplayMode() const override; ui::mojom::WindowShowState GetWindowShowState() override; - blink::mojom::DevicePostureProvider* GetDevicePostureProvider() override; + DevicePostureProviderImpl* GetDevicePostureProvider() override; bool GetResizable() override; void LostPointerLock(RenderWidgetHostImpl* render_widget_host) override; bool HasPointerLock(RenderWidgetHostImpl* render_widget_host) override; diff --git a/third_party/blink/public/mojom/device_posture/device_posture_provider.mojom b/third_party/blink/public/mojom/device_posture/device_posture_provider.mojom index 365e2777..8884bbe7 100644 --- a/third_party/blink/public/mojom/device_posture/device_posture_provider.mojom +++ b/third_party/blink/public/mojom/device_posture/device_posture_provider.mojom @@ -20,11 +20,6 @@ AddListenerAndGetCurrentPosture( pending_remote<DevicePostureClient> client) => (DevicePostureType posture); - - // This is used by DevTools to emulate a device posture. - OverrideDevicePostureForEmulation(DevicePostureType posture); - // This is used by DevTools to disable emulation of a device posture. - DisableDevicePostureOverrideForEmulation(); }; // Interface that client of the DevicePostureProvider interface must implement diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc index 54b76ad1..b1bf68e5 100644 --- a/third_party/blink/renderer/core/frame/local_frame.cc +++ b/third_party/blink/renderer/core/frame/local_frame.cc @@ -1833,15 +1833,6 @@ } } -void LocalFrame::OverrideDevicePostureForEmulation( - mojom::blink::DevicePostureType device_posture_param) { - mojo_handler_->OverrideDevicePostureForEmulation(device_posture_param); -} - -void LocalFrame::DisableDevicePostureOverrideForEmulation() { - mojo_handler_->DisableDevicePostureOverrideForEmulation(); -} - mojom::blink::DevicePostureType LocalFrame::GetDevicePosture() { return mojo_handler_->GetDevicePosture(); } diff --git a/third_party/blink/renderer/core/frame/local_frame.h b/third_party/blink/renderer/core/frame/local_frame.h index 8669b41d..dffb6f5 100644 --- a/third_party/blink/renderer/core/frame/local_frame.h +++ b/third_party/blink/renderer/core/frame/local_frame.h @@ -455,9 +455,6 @@ StyleEnvironmentVariables& vars, const std::vector<gfx::Rect>& viewport_segments); - void OverrideDevicePostureForEmulation( - mojom::blink::DevicePostureType device_posture_param); - void DisableDevicePostureOverrideForEmulation(); mojom::blink::DevicePostureType GetDevicePosture(); String SelectedText() const; diff --git a/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc b/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc index fa8b198..72a0bd2c 100644 --- a/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc +++ b/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc @@ -433,16 +433,6 @@ return current_device_posture_; } -void LocalFrameMojoHandler::OverrideDevicePostureForEmulation( - mojom::blink::DevicePostureType device_posture_param) { - DevicePostureProvider()->OverrideDevicePostureForEmulation( - device_posture_param); -} - -void LocalFrameMojoHandler::DisableDevicePostureOverrideForEmulation() { - DevicePostureProvider()->DisableDevicePostureOverrideForEmulation(); -} - Page* LocalFrameMojoHandler::GetPage() const { return frame_->GetPage(); } diff --git a/third_party/blink/renderer/core/frame/local_frame_mojo_handler.h b/third_party/blink/renderer/core/frame/local_frame_mojo_handler.h index 35f0e927..31b6e33 100644 --- a/third_party/blink/renderer/core/frame/local_frame_mojo_handler.h +++ b/third_party/blink/renderer/core/frame/local_frame_mojo_handler.h
Original Bug Report
Cross-origin device posture spoofing and DoS via OverrideDevicePostureForEmulation
Project Fortify, an experimental security project, has identified the following potential security issue.
Overview: The DevicePostureProvider Mojo interface lacks authorization checks for its DevTools emulation methods. A compromised renderer can spoof the device posture for all frames in a WebContents and block legitimate platform posture updates.
Affected files:
content/browser/device_posture/device_posture_provider_impl.cccontent/browser/browser_interface_binders.ccthird_party/blink/public/mojom/device_posture/device_posture_provider.mojom
Estimated timestamp from git blame: 2025-11-25
Summary
The DevicePostureProvider Mojo interface exposes methods intended for DevTools emulation: OverrideDevicePostureForEmulation and DisableDevicePostureOverrideForEmulation. However, the implementation in the browser process (DevicePostureProviderImpl) lacks any authorization checks. Because this provider is shared across the entire WebContents (tab), a compromised renderer (e.g., in a cross-origin iframe) can call these methods to spoof the device posture for the top-level page and all other frames in the tab. This allows a cross-origin state injection and a tab-scoped Denial of Service (DoS) against the Device Posture API.
Potential Root Cause
- Missing Authorization: In
content/browser/device_posture/device_posture_provider_impl.cc, theOverrideDevicePostureForEmulationmethod accepts a posture type and unconditionally sets an internalis_posture_emulated_flag. It does not check if the caller is privileged (e.g., DevTools) or if the request came from a potentially compromised renderer. - Shared State (WebContents Scope):
DevicePostureProviderImplinherits fromWebContentsUserData<DevicePostureProviderImpl>. This means there is only one instance of this provider per tab, shared among all frames (including cross-origin iframes). - Unconditional Binding: The interface is bound in
content/browser/browser_interface_binders.ccwithinPopulateBinderMapWithContext<RenderFrameHostImpl*>, making it accessible to any frame via theBrowserInterfaceBroker.
Suggested Attacker Steps
(Note: These are potential steps as a working Proof of Concept has not yet been developed and run by our setup.)
- Compromise Renderer: An attacker exploits a vulnerability to gain code execution in a renderer process, potentially one hosting a cross-origin iframe (
attacker.com). - Bind Interface: The compromised renderer uses the
BrowserInterfaceBrokerto request a binding to theblink::mojom::DevicePostureProviderMojo interface. - Trigger Emulation: The attacker sends an IPC message calling
OverrideDevicePostureForEmulation(blink::mojom::DevicePostureType::kFolded)over their bound interface. - State Injection: The browser process unconditionally sets
is_posture_emulated_ = trueand broadcasts the spoofedkFoldedposture to all connectedDevicePostureClientobjects in theWebContents, including the top-level victim document. - Achieve DoS: When the physical device’s posture actually changes (e.g., the user unfolds their phone), the platform provider calls
DevicePostureProviderImpl::OnDevicePostureChanged. Becauseis_posture_emulated_is true, the method early-returns and drops the legitimate update. All frames in the tab are now permanently stuck reflecting the attacker’s spoofed posture.
Suggested Fix
Separate the DevTools emulation methods from the DevicePostureProvider interface into a distinct, privileged Mojo interface (e.g., DevicePostureEmulationProvider) that is only accessible to trusted DevTools clients. Alternatively, implement robust authorization checks within DevicePostureProviderImpl::OverrideDevicePostureForEmulation to ensure the caller has the appropriate permissions to emulate device state.
Evaluated with Chrome root at commit: 0eb4855bda702feaaa8b899336664f97e3df88b8
Results so far have been promising, but there can be wrong deductions. If this proves to be a false positive, please close as WAI; data from false positives will be used to improve accuracy over time. Please feel free to reach out to me if you have concerns or feedback.