CVE-2026-5880
Overview
Files Changed
content/browser/web_contents/web_contents_impl.cc
Patch
From 948f7d11cebca4b17171e7038d93d311db2c5cfa Mon Sep 17 00:00:00 2001 From: Keishi Hattori <[email protected]> Date: Mon, 02 Mar 2026 23:50:36 -0800 Subject: [PATCH] Prevent background tabs from showing PopupWidgetHosts A compromised renderer may try to show a popup to do UI spoofing. Currently, Chromium checks if a tab is visible when *creating* a popup (in CreateNewPopupWidget), but it does not re-verify visibility when the popup is actually *shown* (in ShowCreatedWidget). This CL adds the check to ShowCreatedWidget to close the TOCTOU vulnerability. Bug: 424995036 Change-Id: Ib45df5cf566a95d1da48b386ad55976d2d2366fe Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7593475 Reviewed-by: Avi Drissman <[email protected]> Commit-Queue: Keishi Hattori <[email protected]> Cr-Commit-Position: refs/heads/main@{#1593031} --- diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 64bc568..a4f4036 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc @@ -5776,6 +5776,13 @@ } RenderWidgetHostImpl* render_widget_host_impl = widget_host_view->host(); + + // A background tab cannot show a popup over the active tab. + if (GetVisibility() != Visibility::VISIBLE) { + render_widget_host_impl->ShutdownAndDestroyWidget(true); + return; + } + auto permission_exclusion_area_bounds = PermissionControllerImpl::FromBrowserContext(GetBrowserContext()) ->GetExclusionAreaBoundsInScreen(outermost_web_contents);
Original Bug Report
Compromised renderer can spoof trusted browser UI via PopupWidgetHost
VULNERABILITY DETAILS
The PopupWidgetHost interface [1] allows a renderer to create a popup window, intended for features like dropdown menus. If the renderer is compromised, then it can set arbitrary bounds on the popup window, and paint arbitrary content in it. This allows the attacker to spoof trusted browser UI such as the omnibox, tricking the user into thinking they’re on a different origin.
For simplicity, the attached poc.patch hardcodes the popup window bounds. A real attacker would likely want to adjust the bounds according to the browser window position (window.screenX, window.screenY), the browser window width (window.outerWidth), and the height of the browser UI (window.outerHeight - window.innerHeight). They may also choose to only cover the omnibox, to avoid the need to spoof other UI elements like the tabstrip.
Similarly, the attached poc.patch hardcodes a bitmap to use as the popup window content. A real attacker may generate the content more dynamically so as to match the user’s OS and respond to user input.
The attached poc.patch also doesn’t prevent the user from closing the popup, for example by clicking the page. A real attacker could prevent that by ignoring such clicks [2], or they could simply show a new popup whenever the current one gets closed.
Other examples of what the attacker could use this for include:
- Spoof other security-sensitive UI such as permission prompts, tricking the user into thinking they’re granting permission for some other feature or for some other origin.
- Spoof content or security-sensitive UI relating to other tabs/windows, including those displaying content from other origins. Note that although creating a popup window requires the originating page to be visible [3], showing an already-created popup window doesn’t have that requirement [4], so such spoofs are possible even if the attacker’s page is invisible or occluded (bypassing the fix for https://crbug.com/41494315), by showing the popup window after the user switches to another tab, or by showing it over an auxiliary tab/window created by the attacker via window.open.
- Spoof a credential prompt in its entirety, for example by showing a fake OAuth popup window, or a fake HTTP authentication prompt, or a fake OS-level prompt for user/network credentials.
- Cover the entire screen with an uncloseable attacker-controlled window, perhaps claiming to be ransomware.
VERSION
Chrome Version: 137.0.7151.104 stable
Operating System: Windows 10.0.19045
REPRODUCTION CASE
- Build Chromium with the attached poc.patch, which simulates a compromised renderer.
- Go to https://www.example.com.
- Observe that the URL in the omnibox changes to https://www.google.com, despite the content area displaying https://www.example.com.
BISECT
With the attached poc.patch I can repro on at least:
- Chromium 139.0.7237.0 r1473483 (recent ToT)
- Chromium 137.0.7151.104
- Chromium 108.0.5359.0 r1058968
So the bug has existed for at least a few years and it looks like it impacts all active Chrome release channels including current Chrome 137.0.7151.104 stable.
I tested on Windows but I suspect this applies to other platforms too.
FIX
A potential fix could be to restrict popup windows to the content area (like Firefox does, at least for dropdown menus), and deny attempts to show a popup window if the originating page isn’t active.
CREDIT INFORMATION
Reporter credit: Anonymous
[1] https://chromium.googlesource.com/chromium/src.git/+/186d68e449ac3356147d86062d7e25be371a283b/third_party/blink/public/mojom/page/widget.mojom#229
[2] https://chromium.googlesource.com/chromium/src.git/+/186d68e449ac3356147d86062d7e25be371a283b/third_party/blink/renderer/core/input/event_handler.cc#844
[3] https://chromium.googlesource.com/chromium/src.git/+/186d68e449ac3356147d86062d7e25be371a283b/content/browser/web_contents/web_contents_impl.cc#5446
[4] https://chromium.googlesource.com/chromium/src.git/+/186d68e449ac3356147d86062d7e25be371a283b/content/browser/web_contents/web_contents_impl.cc#5582
- https://chromium.googlesource.com/chromium/src.git/+/186d68e449ac3356147d86062d7e25be371a283b/content/browser/web_contents/web_contents_impl.cc#5446
- https://chromium.googlesource.com/chromium/src.git/+/186d68e449ac3356147d86062d7e25be371a283b/content/browser/web_contents/web_contents_impl.cc#5582
- https://chromium.googlesource.com/chromium/src.git/+/186d68e449ac3356147d86062d7e25be371a283b/third_party/blink/public/mojom/page/widget.mojom#229
- https://chromium.googlesource.com/chromium/src.git/+/186d68e449ac3356147d86062d7e25be371a283b/third_party/blink/renderer/core/input/event_handler.cc#844
- https://crbug.com/41494315
- https://www.example.com
- https://www.google.com