Overview

High
Severity
9.6
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactUse after free in Payments
DescriptionUse after free in Payments
ComponentPayments
Bug ClassUAF
Action tierwatch — corruption primitive but gated (uncommon) — not default-reachable
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.
Tracker553128689
Fix commitf93f6b65c552 (chromium/src) +11/-1
CWECWE-416 (Use-after-free)
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H
CISA KEVNot listed
CreditedGoogle
Reported2026-08-26 (per vendor advisory)
Fix landed2026-09-02 (public git)
Disclosed2026-09-08
Patch gap6 days — fix public in source before the advisory

Background

Web modal dialog
A dialog scoped to a single tab’s WebContents; when shown, SetWebContentsBlocked marks the tab blocked and adjusts its state (including dropping HTML fullscreen).
`WebContents::ExitFullscreen`
Leaves HTML fullscreen, which resizes the browser window and, on Windows, can synchronously dispatch native window-management messages (e.g. WM_WINDOWPOSCHANGED) directly through the window procedure (WndProc).
`WeakPtr` / `GetWeakPtr`
A non-owning pointer that automatically becomes null when its referent is destroyed, so a task bound to it silently no-ops instead of dereferencing a freed object.
Reentrancy UAF
A use-after-free that occurs when a synchronous call runs nested code that destroys an object still referenced by an outer, not-yet-unwound stack frame.

Root Cause Analysis

Per the commit description, the edited code lives in BrowserWindowModalDialogDelegate::SetWebContentsBlocked (the @@ hunk header does not name the enclosing function, so this attribution comes from the commit message, not the diff). When a web modal dialog is shown for a tab that is in HTML fullscreen and lacks AUTOMATIC_FULLSCREEN allow permission, the code called web_contents->ExitFullscreen(true) synchronously while the modal-dialog presentation call frame was still on the stack. On Windows, ExitFullscreen triggers a window resize that dispatches native messages directly via WndProc, which can reentrantly tear down the WebContents and the objects that initiated the dialog (dialog controllers, PaymentRequestState); when control returns up the stack, the presentation code continues to touch those now-freed objects. The invariant violated is that an object must outlive the call frame that is still operating on it.

The fix posts ExitFullscreen as a separate task on the UI thread bound to web_contents->GetWeakPtr(), so it runs only after the current synchronous frame fully unwinds, and is skipped entirely if the WebContents has already been destroyed.

Key insight
The single mistake was performing a fullscreen exit synchronously inside modal-dialog presentation, allowing reentrant native window messages to free objects still live on the stack; deferring it to a posted task guarded by a WeakPtr breaks the reentrancy and neutralizes the dangling reference.

Attack Path

  1. Enter HTML fullscreen A page (renderer-controlled) puts its tab into HTML fullscreen without holding the AUTOMATIC_FULLSCREEN allow content setting.
  2. Trigger a web modal dialog The page initiates a flow that shows a tab-modal dialog (e.g. a Payments/PaymentRequest UI), causing SetWebContentsBlocked to run and reach the synchronous web_contents->ExitFullscreen(true) call.
  3. Reentrant destruction ExitFullscreen resizes the window and, on Windows, synchronously dispatches WM_WINDOWPOSCHANGED through WndProc, which reentrantly destroys the WebContents and the initiating objects such as PaymentRequestState.
  4. Use-after-free As the modal-presentation stack unwinds, still-live frames dereference the freed WebContents/controller objects, producing the UAF. (inferred) Any further exploitation into a controlled read/write or code execution is not shown by the patch.

Impact Assessment

An attacker who can drive a tab into HTML fullscreen and then open a Payments modal dialog can cause a use-after-free in the browser process, giving potential control over freed heap objects. The preconditions are that the tab is in HTML fullscreen without AUTOMATIC_FULLSCREEN permission and that the resize triggers synchronous native window messages (notably on Windows). Escalation beyond the browser-process UAF to information disclosure or code execution is (inferred) and not demonstrated by the diff; the advisory reports this as a use-after-free in Payments and does not state in-the-wild exploitation.

Files Changed

  • chrome/browser/ui/web_modal/browser_window_modal_dialog_delegate.cc

Audit Directions

  • Synchronous fullscreen/window-state changes during UI presentation
    Audit other call sites that invoke ExitFullscreen, window resize, or bounds changes while a dialog, bubble, or modal is being shown, since these can reentrantly dispatch native window messages.
  • Raw pointers across potentially-reentrant calls
    Look for code holding raw WebContents* or controller pointers across any call that can pump messages or run nested loops, and require WeakPtr guards or post-task deferral instead.
  • `SetWebContentsBlocked` and blocking-state handlers
    Review other implementations that react to a tab being blocked/unblocked (across dialog managers and payments/permission flows) for synchronous side effects that assume the WebContents and caller survive the handler.
From f93f6b65c55222664e2c3672a11dc3ee6f81eaec Mon Sep 17 00:00:00 2001
From: Keren Zhu <[email protected]>
Date: Tue, 01 Sep 2026 17:08:27 -0700
Subject: [PATCH] Defer ExitFullscreen when blocking WebContents for modal dialogs

When BrowserWindowModalDialogDelegate::SetWebContentsBlocked is called
upon showing a modal dialog (e.g. via ShowWebModalDialogViews or
TabDialogManager::ShowDialog), it drops HTML fullscreen for the tab.

Calling ExitFullscreen synchronously can trigger direct WndProc calls
(e.g., WM_WINDOWPOSCHANGED on Windows). This can lead to the
WebContents and caller objects (e.g., dialog controllers,
PaymentRequestState) being destroyed synchronously while modal dialog
presentation is still on the stack, resulting in use-after-free
crashes.

This CL posts a task to the UI thread to defer the call to
ExitFullscreen() using a WeakPtr, ensuring the current synchronous
dialog presentation call frame completely unwinds before fullscreen
exit occurs.

TAG=agy
CONV=bce8c045-c1e7-4d88-a581-ff5b1f83ff3c

Bug: 553700283, 540138836, 553128689, 554558968, 553129531
Change-Id: I48e11121ff1a9e33c05705df1869bd749f05b6ee
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8328511
Reviewed-by: Allen Bauer <[email protected]>
Reviewed-by: Thomas Lukaszewicz <[email protected]>
Commit-Queue: Keren Zhu <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1690328}
---
diff --git a/chrome/browser/ui/web_modal/browser_window_modal_dialog_delegate.cc b/chrome/browser/ui/web_modal/browser_window_modal_dialog_delegate.cc
index 96c238d..fd0a7db0 100644
--- a/chrome/browser/ui/web_modal/browser_window_modal_dialog_delegate.cc
+++ b/chrome/browser/ui/web_modal/browser_window_modal_dialog_delegate.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/ui/web_modal/browser_window_modal_dialog_delegate.h"
 
+#include "base/functional/bind.h"
 #include "base/types/to_address.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
 #include "chrome/browser/devtools/devtools_ui_controller.h"
@@ -20,6 +21,8 @@
 #include "components/content_settings/core/common/content_settings.h"
 #include "components/content_settings/core/common/content_settings_types.h"
 #include "components/web_modal/web_contents_modal_dialog_host.h"
+#include "content/public/browser/browser_task_traits.h"
+#include "content/public/browser/browser_thread.h"
 #include "content/public/browser/web_contents.h"
 
 DEFINE_USER_DATA(BrowserWindowModalDialogDelegate);
@@ -73,7 +76,14 @@
       if (content_settings->GetContentSetting(
               url, url, ContentSettingsType::AUTOMATIC_FULLSCREEN) !=
           CONTENT_SETTING_ALLOW) {
-        web_contents->ExitFullscreen(true);
+        // Defer exiting fullscreen to prevent synchronous window management
+        // messages (e.g. direct WndProc calls on Windows) from destroying the
+        // WebContents or callers while modal dialog presentation is on the
+        // stack.
+        content::GetUIThreadTaskRunner({})->PostTask(
+            FROM_HERE, base::BindOnce(&content::WebContents::ExitFullscreen,
+                                      web_contents->GetWeakPtr(),
+                                      /*will_cause_resize=*/true));
       }
     }
   }
Loading diff…

Original Bug Report

The reporter's bug is still restricted on the tracker. Chrome de-restricts security bugs ~30–90 days after the fix ships; a later run will backfill it here.