Overview

Low
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactInsufficient policy enforcement in FoldableAPIs
DescriptionInsufficient policy enforcement in FoldableAPIs
ComponentFoldableAPIs
Bug ClassLogic Error
Tracker496095145
Fix commit829bf4ec033c (chromium/src) +9/-60
CISA KEVNot listed
CreditedGoogle
Disclosed2026-06-02

Changed Functions

FunctionChangeNotes
if
content/browser/devtools/protocol/emulation_handler.cc
modified
GetDevicePostureProvider
content/browser/renderer_host/render_widget_host_delegate.cc
modified
RenderFrameProxyHost
content/browser/renderer_host/render_widget_host_delegate.h
modified
RenderWidgetHostImpl
content/browser/renderer_host/render_widget_host_delegate.h
modified
DevicePostureProviderImpl
content/browser/renderer_host/render_widget_host_delegate.h
modified
RenderWidgetHostViewBase
content/browser/renderer_host/render_widget_host_delegate.h
modified
RenderViewHostDelegateView
content/browser/renderer_host/render_widget_host_delegate.h
modified
TextInputManager
content/browser/renderer_host/render_widget_host_delegate.h
modified
GetDevicePostureProvider
content/browser/web_contents/web_contents_impl.cc
modified

Files Changed

  • content/browser/device_posture/device_posture_provider_impl.h
  • content/browser/devtools/protocol/emulation_handler.cc
  • content/browser/renderer_host/render_widget_host_delegate.cc
  • content/browser/renderer_host/render_widget_host_delegate.h
  • content/browser/web_contents/web_contents_impl.cc
  • content/browser/web_contents/web_contents_impl.h
  • third_party/blink/public/mojom/device_posture/device_posture_provider.mojom
  • third_party/blink/renderer/core/frame/local_frame.cc
  • third_party/blink/renderer/core/frame/local_frame.h
  • third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc
  • third_party/blink/renderer/core/frame/local_frame_mojo_handler.h
From 829bf4ec033ca45078c880a193c73fa6c534c37c Mon Sep 17 00:00:00 2001
From: Menard, Alexis <alexis.menard@intel.com>
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 <boliu@chromium.org>
Commit-Queue: Menard, Alexis <alexis.menard@intel.com>
Reviewed-by: Reilly Grant <reillyg@chromium.org>
Reviewed-by: Dominic Farolino <dom@chromium.org>
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
Loading diff…

Original Bug Report

reported by vm...@google.com

Remove DevicePostureProvider emulation methods to prevent Site Isolation bypass

Project Fortify, an experimental security project, has identified the following potential security issue.

Overview: A compromised renderer can invoke DevTools emulation methods on the shared DevicePostureProviderImpl to broadcast a spoofed posture to all cross-origin frames in the tab. This allows cross-origin UI redressing and covert channels. Moving these methods to a privileged interface resolves the issue.

Affected files:

  • content/browser/device_posture/device_posture_provider_impl.cc
  • content/browser/browser_interface_binders.cc
  • third_party/blink/public/mojom/device_posture/device_posture_provider.mojom
  • content/browser/device_posture/device_posture_provider_impl.h

Estimated timestamp from git blame: 2025-11-25

Final Resolution

The vulnerability requires removing OverrideDevicePostureForEmulation and DisableDevicePostureOverrideForEmulation from the public blink.mojom.DevicePostureProvider interface. DevTools must route emulation commands through a restricted, privileged channel or direct C++ calls to DevicePostureProviderImpl.

Vulnerability Summary

Initial Mojo binding logic in content/browser/browser_interface_binders.cc and the WebContentsUserData singleton scoping of DevicePostureProviderImpl are validated.

The exploit leap occurs during the state mutation and broadcast phase. When any renderer (including a compromised cross-origin subframe) invokes the exposed OverrideDevicePostureForEmulation method, the browser unconditionally executes the global broadcast:

// content/browser/device_posture/device_posture_provider_impl.cc:60
is_posture_emulated_ = true;
for (auto& client : posture_clients_) {
  client->OnPostureChanged(emulated_posture);
}

Because posture_clients_ aggregates listeners from all frames across the entire WebContents, this loop forcibly pushes the attacker-controlled posture state (e.g., kFolded) across Site Isolation boundaries directly into victim renderers, triggering authoritative CSS media query shifts.

Potential Attack Steps

Note: These are suggested/potential steps, as our setup does not currently have the ability to run code to produce a working proof of concept.

  1. Attacker achieves code execution in a subframe renderer process.
  2. Attacker retrieves the blink.mojom.DevicePostureProvider remote via BrowserInterfaceBroker.
  3. Attacker invokes OverrideDevicePostureForEmulation(DevicePostureType::kFolded).
  4. Victim’s top-level or cross-origin frame synchronously receives the event, evaluating @media(device-posture:folded) to manipulate the target UI or establish a cross-origin covert channel.

Suggested Fix

Remove the DevTools emulation overrides from the renderer-exposed DevicePostureProvider Mojo interface and migrate them to a secure DevTools-specific protocol handler.

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.

View on issue tracker