CVE-2026-87653
Overview
Background
- HTML fullscreen
- a mode where a web page occupies the entire display and controls all rendered pixels, so any additional browser UI drawn on top can be visually framed by attacker-controlled content.
- Emoji panel
- a modeless (non-modal) OS/browser UI surfaced by
BrowserView::ShowEmojiPanel()that lets the user insert emoji into a focused input. - `ForSecurityDropFullscreen`
- a
content::WebContentsmethod that exits any active HTML fullscreen for security reasons; here it is passeddisplay::kInvalidDisplayIdand its boolean result is used to gate further UI. - `SetWebContentsBlocked`
- the mechanism through which modal dialogs already force fullscreen to drop, which the emoji panel (being modeless) never triggers.
Root Cause Analysis
BrowserView::ShowEmojiPanel() previously called GetWidget()->ShowEmojiPanel() directly without touching the fullscreen state of the active tab. Because the emoji panel is modeless UI, it does not go through SetWebContentsBlocked the way modal dialogs do, so no code path dropped HTML fullscreen before the panel appeared. This let a page that had entered HTML fullscreen keep controlling the full display while the emoji panel was overlaid on top of its attacker-drawn content, violating the invariant that trusted, page-independent UI should not be presented while the page still owns the entire screen.
The fix adds a guard that fetches the active content::WebContents via GetActiveWebContents() and calls web_contents->ForSecurityDropFullscreen(display::kInvalidDisplayId), dropping fullscreen before the panel is shown; if that call reports it did not proceed, the function returns early and the panel is not shown at all. The change strictly tightens behavior — it adds a mandatory fullscreen-exit step that did not exist before.
SetWebContentsBlocked, leaving it displayable over attacker-controlled fullscreen content. The fix closes this by explicitly calling ForSecurityDropFullscreen in ShowEmojiPanel() so the page loses control of the screen before the panel is drawn.Attack Path
- Enter HTML fullscreen A malicious page requests HTML fullscreen so it controls the entire display and can paint arbitrary fake browser or OS chrome.
- Trigger the emoji panel
The user (or a page nudging the user via a focused text field) invokes the emoji panel, which reaches
BrowserView::ShowEmojiPanel(). - Panel shown over fullscreen
Pre-patch,
GetWidget()->ShowEmojiPanel()runs without dropping fullscreen, so the modeless panel is composited on top of the still-fullscreen, attacker-controlled page. - Spoof surrounding UI The page draws deceptive UI around the emoji panel to misrepresent context or origin, achieving UI spoofing in the fullscreen surface (specific spoofed elements are page-defined and not shown by the patch) (inferred).
Impact Assessment
Files Changed
chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.ccchrome/browser/ui/views/frame/browser_view.cc
Audit Directions
- Modeless UI over fullscreenAudit other modeless surfaces (spell-check menus, color/date pickers, autofill and other non-modal popups) that are shown without routing through the modal
SetWebContentsBlockedpath, and confirm each drops HTML fullscreen before display. - Missing `ForSecurityDropFullscreen` callsSearch
BrowserViewand related browser-window UI entry points that surface chrome-owned UI to verify they invokeForSecurityDropFullscreen(or an equivalent) when the active tab may be in HTML fullscreen. - Platform-specific UI entry pointsReview OS-integrated panels (emoji/character pickers, IME candidate windows) whose visibility bypasses Chromium’s normal modal machinery, since these are prone to appearing over attacker-controlled fullscreen content.
Patch
From 20d7987766164047277a239abad097365106b413 Mon Sep 17 00:00:00 2001 From: Jordan Bayles <[email protected]> Date: Thu, 30 Jul 2026 11:43:58 -0700 Subject: [PATCH] [security] drop fullscreen when showing emoji panel in BrowserView Ensure showing the emoji panel drops HTML fullscreen on the active WebContents in BrowserView::ShowEmojiPanel(). Unlike modal dialogs (which automatically drop fullscreen via SetWebContentsBlocked), the emoji panel is modeless UI. Dropping fullscreen when the emoji panel is invoked prevents webpage UI spoofing under the emoji overlay. Added interactive browser test FullscreenControllerInteractiveTest.ShowEmojiPanelExitsFullscreen to verify the behavior. Fixed: 40058710 Change-Id: I1c1faf1d21911886b74732216137dab459a00753 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8166148 Reviewed-by: Avi Drissman <[email protected]> Commit-Queue: Jordan Bayles <[email protected]> Cr-Commit-Position: refs/heads/main@{#1671281} --- diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index f46ffa0..14ee3061 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc @@ -5792,6 +5792,15 @@ } void BrowserView::ShowEmojiPanel() { + // Unlike modal dialogs (which drop fullscreen via SetWebContentsBlocked), + // the emoji panel is non-modal UI that can interfere with the fullscreen + // bubble. Drop fullscreen when showing the emoji panel to prevent UI + // spoofing. + if (content::WebContents* web_contents = GetActiveWebContents()) { + if (!web_contents->ForSecurityDropFullscreen(display::kInvalidDisplayId)) { + return; + } + } GetWidget()->ShowEmojiPanel(); } diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc b/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc index f5c1ba5..c339bf7 100644 --- a/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc +++ b/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc @@ -948,6 +948,18 @@ } IN_PROC_BROWSER_TEST_F(FullscreenControllerInteractiveTest, + ShowEmojiPanelExitsFullscreen) { + ASSERT_NO_FATAL_FAILURE(ToggleTabFullscreen(true)); + ASSERT_TRUE(IsWindowFullscreenForTabOrPending()); + + ui_test_utils::FullscreenWaiter waiter(browser(), {.tab_fullscreen = false}); + BrowserWindow::FromBrowser(browser()->GetBrowserForMigrationOnly()) + ->ShowEmojiPanel(); + waiter.Wait(); + EXPECT_FALSE(IsWindowFullscreenForTabOrPending()); +} + +IN_PROC_BROWSER_TEST_F(FullscreenControllerInteractiveTest, CapturedContentEntersFullscreenWithinTab) { SetDisableFullscreenWithinTab(false); // Simulate tab capture, as used by getDisplayMedia() content sharing.
Regression Test / PoC
diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc b/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc
index f5c1ba5..c339bf7 100644
--- a/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc
+++ b/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc
@@ -948,6 +948,18 @@
}
IN_PROC_BROWSER_TEST_F(FullscreenControllerInteractiveTest,
+ ShowEmojiPanelExitsFullscreen) {
+ ASSERT_NO_FATAL_FAILURE(ToggleTabFullscreen(true));
+ ASSERT_TRUE(IsWindowFullscreenForTabOrPending());
+
+ ui_test_utils::FullscreenWaiter waiter(browser(), {.tab_fullscreen = false});
+ BrowserWindow::FromBrowser(browser()->GetBrowserForMigrationOnly())
+ ->ShowEmojiPanel();
+ waiter.Wait();
+ EXPECT_FALSE(IsWindowFullscreenForTabOrPending());
+}
+
+IN_PROC_BROWSER_TEST_F(FullscreenControllerInteractiveTest,
CapturedContentEntersFullscreenWithinTab) {
SetDisableFullscreenWithinTab(false);
// Simulate tab capture, as used by getDisplayMedia() content sharing.
Original Bug Report
Issue 1170584: UI/URL Spoofing by putting the page into fullscreen when a user opens the emoji dialog
UserAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.82 Safari/537.36
Steps to reproduce the problem: https://crbug.com/chromium/1170584: UI/URL Spoofing by putting the page into fullscreen when a user opens the emoji dialog is not resolved
What is the expected behavior?
What went wrong? UI/URL Spoofing by putting the page into fullscreen when a user opens the emoji dialog is not resolved in new version
Did this work before? N/A
Chrome version: 98.0.4758.82 Channel: n/a OS Version: 10.0