Overview

Low
Severity
5.4
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactUI misrepresentation in FullScreen
DescriptionUI misrepresentation in FullScreen
ComponentFullScreen
Sub-componentSecurity
Bug ClassSpoofing
Action tierwatch — logic/policy bug — security-relevant, no memory-unsafety
Computed by PatchGap's deterministic exploitability ruler from the fixing commit. patch-now = RCE-class & attacker-reachable in a default config, or exploited in the wild; watch = real security signal below that bar; noise = no security relevance.
Tracker40058710
Fix commit20d798776616 (chromium/src) +21/-0
CWECWE-451
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:L
CISA KEVNot listed
CreditedLijo A.T
Reported2022-02-07 · bounty $500 (per vendor advisory)
Fix landed2026-07-30 (public git)
Disclosed2026-09-08
Patch gap40 days — fix public in source before the advisory

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::WebContents method that exits any active HTML fullscreen for security reasons; here it is passed display::kInvalidDisplayId and 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.

Key insight
The single mistake was treating the modeless emoji panel like ordinary UI while forgetting it never inherits the modal-dialog path that drops fullscreen through 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

  1. Enter HTML fullscreen A malicious page requests HTML fullscreen so it controls the entire display and can paint arbitrary fake browser or OS chrome.
  2. 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().
  3. 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.
  4. 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

An attacker gains a UI-misrepresentation/spoofing primitive in the browser UI context: while a page holds HTML fullscreen, the modeless emoji panel could be shown over attacker-controlled content, letting the page frame or spoof surrounding UI. The precondition is that the page has entered HTML fullscreen and the emoji panel is invoked while in that state. The advisory classifies this as a Spoofing bug (UI misrepresentation in FullScreen); no memory-safety, code-execution, or sandbox-escape escalation is indicated, and any impact beyond visual spoofing would be (inferred).

Files Changed

  • chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc
  • chrome/browser/ui/views/frame/browser_view.cc

Audit Directions

  • Modeless UI over fullscreen
    Audit other modeless surfaces (spell-check menus, color/date pickers, autofill and other non-modal popups) that are shown without routing through the modal SetWebContentsBlocked path, and confirm each drops HTML fullscreen before display.
  • Missing `ForSecurityDropFullscreen` calls
    Search BrowserView and related browser-window UI entry points that surface chrome-owned UI to verify they invoke ForSecurityDropFullscreen (or an equivalent) when the active tab may be in HTML fullscreen.
  • Platform-specific UI entry points
    Review 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.
From 20d7987766164047277a239abad097365106b413 Mon Sep 17 00:00:00 2001
From: Jordan Bayles <jophba@chromium.org>
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 <avi@chromium.org>
Commit-Queue: Jordan Bayles <jophba@chromium.org>
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.
Loading diff…

Regression Test / PoC

shipped with the fix
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.
Loading diff…

Original Bug Report

reported by li...@gmail.com

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

View on issue tracker