Overview

Critical
Severity
8.3
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactUse after free in Aura
DescriptionUse after free in Aura
ComponentAura
Bug ClassUAF
Action tierwatch — corruption primitive but gated (uncommon) — not default-reachable — revised by independent review by AI
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.
Independent review by AIPlausible (tier revised from patch-now)
Reviewer notes: Diff confirms a WeakPtr guard after ShowImpl on Windows only, but not what destroys the view or that web content can trigger it; 'unconditionally' is overstated (shown access is gated by page_visibility). Default web reachability is unsupported.
A second, independent AI reviewer (not a human) re-derived this analysis from the fixing commit and the vendor advisory, looking for errors.
Tracker516691130
Fix commitd86edd3226e2 (chromium/src) +7/-0
CWECWE-416 (Use-after-free)
CVSS vectorCVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:H/A:H
CISA KEVNot listed
CreditedGoogle
Reported2026-05-26 (per vendor advisory)
Fix landed2026-05-28 (public git)
Disclosed2026-06-08
Patch gap11 days — fix public in source before the advisory

Background

`RenderWidgetHostViewAura`
The Aura-backed implementation of a render widget host view in the browser process that owns platform-specific resources such as legacy_render_widget_host_HWND_.
`base::WeakPtr`
A smart pointer that becomes null once the object it references is destroyed, letting callers detect that a this object was freed mid-call.
`weak_ptr_factory_`
The per-object factory whose GetWeakPtr() hands out base::WeakPtr references that track the lifetime of the owning RenderWidgetHostViewAura.
`legacy_render_widget_host_HWND_`
The Windows-only legacy HWND member accessed after ShowImpl to hide the widget when the page is not visible.

Root Cause Analysis

Verify before building a PoC

This analysis is consistent with the fixing commit but not fully provable from it: part of the vulnerable path lives in code the fix commit does not touch. Confirm the trigger and the sink against the source before relying on it for exploit development.
What the commit does not establish: Diff confirms a WeakPtr guard after ShowImpl on Windows only, but not what destroys the view or that web content can trigger it; 'unconditionally' is overstated (shown access is gated by page_visibility). Default web reachability is unsupported.

In RenderWidgetHostViewAura::ShowWithVisibility, the code called window_->Show() and then ShowImpl(page_visibility) before unconditionally touching the Windows-only member legacy_render_widget_host_HWND_. Showing the view can synchronously re-enter code that destroys the RenderWidgetHostViewAura instance, so by the time control returned from ShowImpl the this object could already be freed, yet execution continued into the #if BUILDFLAG(IS_WIN) block that dereferences legacy_render_widget_host_HWND_. The violated invariant is that this must remain valid across the call to ShowImpl before any further member access; nothing guaranteed that after a re-entrant destruction.

The fix captures a base::WeakPtr<RenderWidgetHostViewAura> weak_this from weak_ptr_factory_.GetWeakPtr() immediately before ShowImpl, then checks if (!weak_this) { return; } on Windows, bailing out safely when the view was destroyed and preventing the use-after-free.

Key insight
The core mistake was accessing member state (legacy_render_widget_host_HWND_) after ShowImpl(page_visibility) without accounting for the possibility that ShowImpl synchronously destroys the RenderWidgetHostViewAura; the fix detects that destruction via a base::WeakPtr guard and returns before any post-ShowImpl member access.

Attack Path

  1. Trigger a show on Windows Cause a RenderWidgetHostViewAura to be shown so that ShowWithVisibility runs window_->Show() and then ShowImpl(page_visibility) on a Windows build.
  2. Re-enter and destroy the view Arrange for the show path to synchronously re-enter browser code that tears down and frees the same RenderWidgetHostViewAura during ShowImpl.
  3. Fall through to freed member access After ShowImpl returns, execution continues into the #if BUILDFLAG(IS_WIN) block and dereferences legacy_render_widget_host_HWND_ on the now-freed object.
  4. Exploit the dangling access Groom the freed allocation so the use-after-free read or Hide() call operates on attacker-controlled memory, gaining control over browser-process state.

Impact Assessment

An attacker who can drive view creation and destruction timing gains a use-after-free in the browser process on Windows, reading from or invoking a method on a freed RenderWidgetHostViewAura via legacy_render_widget_host_HWND_. Preconditions are a Windows build and the ability to trigger a re-entrant destruction of the view during ShowImpl, which combined with heap grooming can lead to memory corruption and potential sandbox-escaping code execution.

Changed Functions

FunctionChangeNotes
if
content/browser/renderer_host/render_widget_host_view_aura.cc
modified

Files Changed

  • content/browser/renderer_host/render_widget_host_view_aura.cc

Audit Directions

  • Re-entrant destruction after callbacks
    Look for methods that continue touching this members after calling into functions like ShowImpl, Show, or observer notifications that can synchronously destroy the object.
  • Platform-guarded tails
    Scrutinize #if BUILDFLAG(IS_WIN) and other platform-specific tails that run after a potentially destructive call without a base::WeakPtr lifetime check.
  • View lifetime across visibility changes
    Audit RenderWidgetHostViewAura visibility and show/hide paths where window_->Show() or similar can trigger nested teardown before later member dereferences.
From d86edd3226e233b4556c7fc7022042824806e3d9 Mon Sep 17 00:00:00 2001
From: Kartar Singh <kartarsingh@google.com>
Date: Thu, 28 May 2026 09:41:03 -0700
Subject: [PATCH] Prevent Use-After-Free in RenderWidgetHostViewAura::ShowWithVisibility.

Use base::WeakPtr to guard against view destruction during ShowImpl
on Windows builds.

Bug: 516691130
Change-Id: I857c1900ab55f6b0d26e54db35652df4d14d32b8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7883318
Reviewed-by: Jonathan Ross <jonross@chromium.org>
Commit-Queue: Kartar Singh <kartarsingh@google.com>
Cr-Commit-Position: refs/heads/main@{#1637761}
---

diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index 3c0b9aeb..2575c2a 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -1042,8 +1042,15 @@
   }
 
   window_->Show();
+
+  base::WeakPtr<RenderWidgetHostViewAura> weak_this(
+      weak_ptr_factory_.GetWeakPtr());
+
   ShowImpl(page_visibility);
 #if BUILDFLAG(IS_WIN)
+  if (!weak_this) {
+    return;
+  }
   if (page_visibility != PageVisibilityState::kVisible &&
       legacy_render_widget_host_HWND_) {
     legacy_render_widget_host_HWND_->Hide();
Loading diff…

Original Bug Report

reported by vm...@google.com

Potential Use-After-Free in RenderWidgetHostViewAura::ShowWithVisibility on Windows

Project Fortify, an experimental security project, has identified the following potential security issue. If you’re a feature owner CC-ed on this bug, please do your best to review these reports. Please see https://chromium.googlesource.com/chromium/src/+/main/docs/security/ai-generated-security-bugs-faq.md for more information.

Overview: A potential Use-After-Free (UAF) vulnerability exists in RenderWidgetHostViewAura::ShowWithVisibility on Windows due to a missing lifetime check. When calling ShowImpl, a nested message loop can be spun during parent or bounds updates of the legacy window, allowing re-entrant window destruction events to delete the view. Upon returning from ShowImpl, the function dereferences members of the already-freed this object.

Affected files:

  • content/browser/renderer_host/render_widget_host_view_aura.cc

Estimated timestamp from git blame: 2021-01-28

Summary

A potential Use-After-Free (UAF) vulnerability exists in the browser process of Chromium on Windows. The issue is located in RenderWidgetHostViewAura::ShowWithVisibility inside content/browser/renderer_host/render_widget_host_view_aura.cc. When ShowImpl is executed, it can transitively call Win32 windowing APIs that synchronously dispatch messages and spin a nested message loop. If a window close or destruction event is handled during this nested loop, the RenderWidgetHostViewAura instance is deleted. While intermediate functions contain safety guards, the parent method ShowWithVisibility fails to check if the instance is still alive before dereferencing this.

Technical Analysis

In content/browser/renderer_host/render_widget_host_view_aura.cc, the method RenderWidgetHostViewAura::ShowWithVisibility executes the following sequence:

void RenderWidgetHostViewAura::ShowWithVisibility(
    PageVisibilityState page_visibility) {
  ...
  window_->Show();
  ShowImpl(page_visibility);
#if BUILDFLAG(IS_WIN)
  if (page_visibility != PageVisibilityState::kVisible &&
      legacy_render_widget_host_HWND_) {
    legacy_render_widget_host_HWND_->Hide();
  }
#endif  // BUILDFLAG(IS_WIN)
}

The call to ShowImpl(page_visibility) eventually routes to NotifyHostAndDelegateOnWasShown, which triggers UpdateLegacyWin() on Windows. Inside UpdateLegacyWin(), Win32 API calls such as ::SetParent or ::SetWindowPos are performed:

if (legacy_render_widget_host_HWND_) {
  base::WeakPtr<RenderWidgetHostViewAura> weak_this(
      weak_ptr_factory_.GetWeakPtr());
  legacy_render_widget_host_HWND_->UpdateParent(GetHostWindowHWND());
  if (!weak_this) { return; }
  legacy_render_widget_host_HWND_->SetBounds(window_->GetBoundsInRootWindow());
  if (!weak_this) { return; }

As noted in the developer comments, both UpdateParent and SetBounds can synchronously dispatch window messages and spin a nested event loop. If a window close/destruction event is dispatched during this nested pump, the re-entrant dispatch reaches RenderWidgetHostViewAura::OnWindowDestroyed, which executes delete this;.

Although UpdateLegacyWin and intermediate functions correctly utilize a WeakPtr guard to return immediately upon destruction, the top-level ShowWithVisibility method lacks this protection. After ShowImpl() returns, the stack unwinds back to ShowWithVisibility, which immediately attempts to read legacy_render_widget_host_HWND_ from the freed this object, resulting in a Use-After-Free.

Because this is a bare stack reference at the call site, MiraclePtr (BackupRefPtr) does not protect against or mitigate this UAF.

Potential Trigger Steps

Note: These are potential, theoretical steps as our automated tooling does not have the capability to run code.

  1. Open a same-origin popup window using window.open().
  2. Force a page visibility transition to a non-visible but active state, such as PageVisibilityState::kHiddenButPainting (e.g., via tab capture or background Picture-in-Picture).
  3. Race this visibility change with a window close event (e.g., by sending a widget close IPC from a compromised renderer or calling window.close() on the popup) so that the destruction message is processed during the synchronous Win32 API calls (::SetParent or ::SetWindowPos) inside UpdateLegacyWin().
  4. When the nested loop terminates, the call stack unwinds to ShowWithVisibility, which dereferences the freed RenderWidgetHostViewAura instance when evaluating legacy_render_widget_host_HWND_.

Suggested Fix

Introduce a WeakPtr check in ShowWithVisibility immediately after returning from ShowImpl to prevent dereferencing the deleted this pointer:

void RenderWidgetHostViewAura::ShowWithVisibility(
    PageVisibilityState page_visibility) {
  UpdateScreenInfo();

  if (!window_->GetLocalSurfaceId().is_valid()) {
    window_->AllocateLocalSurfaceId();
    SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
                                window_->GetLocalSurfaceId());
  }

  base::WeakPtr<RenderWidgetHostViewAura> weak_this(
      weak_ptr_factory_.GetWeakPtr());

  window_->Show();
  ShowImpl(page_visibility);

#if BUILDFLAG(IS_WIN)
  if (!weak_this) {
    return;
  }
  if (page_visibility != PageVisibilityState::kVisible &&
      legacy_render_widget_host_HWND_) {
    legacy_render_widget_host_HWND_->Hide();
  }
#endif  // BUILDFLAG(IS_WIN)
}

Evaluated with Chrome root at commit: a2bea94528f4bd6cc57739c43fa3bb890b8367d3


Results so far have been promising, but there can be wrong deductions. Feel free to adjust as follows:

  • If you are familiar with the severity guidelines, you may adjust the severity.
  • If this is a false positive, and there’s no work to be done, please close as WAI.
  • If there is work to do here but not a vulnerability, please change the issue type to Task/Bug/FR.

Data from false positives will be used to improve accuracy over time. And please feel free to reach out to me directly if you have concerns or feedback on the project.

View on issue tracker