High watch ✔︎ verified CVSS 7.5 chrome UAF 📄 Reporter bug report 🔧 Commit mapped

Overview

High
Severity
7.5
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactUse after free in WebAppInstalls
DescriptionUse after free in WebAppInstalls
ComponentWebAppInstalls
Sub-componentUI>Browser>WebAppInstalls
Bug ClassUAF
Action tierwatch — corruption primitive but gated (uncommon) — not default-reachable — factors set 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 AIConfirmed
A second, independent AI reviewer (not a human) re-derived this analysis from the fixing commit and the vendor advisory, looking for errors.
Tracker513750089
Fix commit6c5b35aa5096 (chromium/src) +25/-0
CWECWE-416 (Use-after-free)
CVSS vectorCVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H
CISA KEVNot listed
CreditedGoogle
Reported2026-05-16 (per vendor advisory)
Fix landed2026-05-18 (public git)
Disclosed2026-05-27
Patch gap9 days — fix public in source before the advisory

Background

`AppShimApplication`
the NSApplication subclass used by Chrome’s macOS app shim process, including PWAs (app_shim_application.mm:11).
`_selectWindow:`
an AppKit action sent when the user picks a window from the Dock menu’s automatic window list (app_shim_application.mm diff, added guard).
Dock menu window list
AppKit snapshots the open windows when the Dock menu is shown and keeps raw pointers to those NSWindows while the menu is up.

Root Cause Analysis

Pre-fix, AppShimApplication (app_shim_application.mm:11-68) implements several NSApplication overrides but has no -sendAction:to:from: override, so every action — including _selectWindow: from the Dock menu — is dispatched straight to AppKit. The invariant required for Dock-menu window selection is that the target window still exists when the action fires, but AppKit’s Dock menu holds raw pointers to the windows it snapshotted and does not drop them if a window is closed while the menu is open. If a window is destroyed (e.g. a PWA closing a popup) while its Dock-menu entry persists, selecting that entry dispatches _selectWindow: to a freed NSWindow, i.e. an Objective-C message send on freed memory.

The fix adds a -sendAction:to:from: override (app_shim_application.mm diff): when anAction == @selector(_selectWindow:), it iterates for (NSWindow* window in [self windows]) comparing each against aTarget by pointer, and if no match is found it returns NO instead of calling super. The comment notes it deliberately avoids -[NSArray containsObject:] “because |aTarget| may be a freed object,” comparing raw pointers rather than messaging the target. This duplicates the guard that already existed in the browser’s application subclass, closing the gap for the shim process; a follow-up CL is noted to refactor the shared logic.

Key insight
The app-shim NSApplication subclass was missing the browser’s _selectWindow: validation, so a stale Dock-menu window pointer was dispatched without a liveness check; the fix validates the target against the live window list and short-circuits when it is gone.

Attack Path

  1. Open a shim window A PWA opens a secondary window in the app shim process. (inferred trigger per reporter)
  2. Show the Dock menu The user right-clicks the shim’s Dock icon, so AppKit snapshots the window list including that window.
  3. Close the window While the menu is open, the PWA closes the window, freeing the underlying NSWindow. (inferred that JS close frees it)
  4. Select the stale entry Choosing the closed window’s menu entry sends _selectWindow: to the freed object; pre-fix this reaches AppKit with no liveness check (app_shim_application.mm had no sendAction:to:from: override).
  5. Reclaim the memory An attacker who grooms the heap to reoccupy the freed slot could influence the dispatch. (inferred)

Impact Assessment

An attacker-controlled PWA could cause an Objective-C dispatch to a freed NSWindow in the app shim process, which the advisory notes runs unsandboxed on macOS. The advisory rates this high severity with no in-the-wild exploitation. Escalation from the use-after-free to code execution is (inferred) from the reporter; the shown code only establishes the missing liveness guard.

Changed Functions

FunctionChangeNotes
for
chrome/app_shim/app_shim_application.mm
modified
if
chrome/app_shim/app_shim_application.mm
modified

Files Changed

  • chrome/app_shim/app_shim_application.mm

Audit Directions

  • Subclass parity for security guards
    When one NSApplication/platform subclass adds a safety override, audit sibling subclasses (here the shim) for the same guard.
  • AppKit raw-pointer snapshots
    Treat any AppKit feature that caches window/object pointers (Dock menu, services) as a source of stale pointers across async teardown.
  • Validate action targets before dispatch
    Short-circuit actions whose target may have been freed by checking a live collection with pointer comparison rather than messaging the target.
From 6c5b35aa509605188466f9d3a0472f345866be8b Mon Sep 17 00:00:00 2001
From: Marijn Kruisselbrink <[email protected]>
Date: Mon, 18 May 2026 13:06:42 -0700
Subject: [PATCH] Fix Use-After-Free in AppShimApplication via Dock Menu

When a window is closed while the Dock menu is open, selecting it from
the Dock menu triggers the '_selectWindow:' action on a freed window
pointer. Short-circuit this action by validating the target window
before forwarding it to super.

This duplicates logic from CrBrowserApplication, but this will be
refactored in a follow-up CL by adding a common base class.

Bug: 513750089
Change-Id: I8aaa24e1298ffef543f3fa4a2b09896e9d7bab2e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7855918
Reviewed-by: Avi Drissman <[email protected]>
Commit-Queue: Marijn Kruisselbrink <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1632360}
---

diff --git a/chrome/app_shim/app_shim_application.mm b/chrome/app_shim/app_shim_application.mm
index 319232f..055a589 100644
--- a/chrome/app_shim/app_shim_application.mm
+++ b/chrome/app_shim/app_shim_application.mm
@@ -57,6 +57,31 @@
   return [super accessibilitySetValue:value forAttribute:attribute];
 }
 
+- (BOOL)sendAction:(SEL)anAction to:(id)aTarget from:(id)sender {
+  // The Dock menu contains an automagic section where you can select
+  // amongst open windows.  If a window is closed via JavaScript while
+  // the menu is up, the menu item for that window continues to exist.
+  // When a window is selected this method is called with the
+  // now-freed window as |aTarget|.  Short-circuit the call if
+  // |aTarget| is not a valid window.
+  if (anAction == @selector(_selectWindow:)) {
+    // Not using -[NSArray containsObject:] because |aTarget| may be a
+    // freed object.
+    BOOL found = NO;
+    for (NSWindow* window in [self windows]) {
+      if (window == aTarget) {
+        found = YES;
+        break;
+      }
+    }
+    if (!found) {
+      return NO;
+    }
+  }
+
+  return [super sendAction:anAction to:aTarget from:sender];
+}
+
 - (NSAccessibilityRole)accessibilityRole {
   AppShimDelegate* delegate =
       base::apple::ObjCCastStrict<AppShimDelegate>(NSApp.delegate);
Loading diff…

Original Bug Report

reported by [email protected]

Potential Use-After-Free in unsandboxed AppShimApplication via Dock Menu

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: AppShimApplication lacks a security guard in sendAction:to:from: that exists in BrowserCrApplication to prevent a Use-After-Free (UAF) condition. This allows a malicious Progressive Web App (PWA) to potentially trigger memory corruption and code execution in the unsandboxed app shim process. The vulnerability occurs when a window is closed while the macOS Dock menu is displaying it, leading to a stale pointer dispatch.

Affected files:

  • chrome/app_shim/app_shim_application.mm
  • chrome/app_shim/app_shim_application.h

Estimated timestamp from git blame: 2019-01-29

Description

In Chromium on macOS, BrowserCrApplication (the NSApplication subclass for the browser process) overrides -[NSApplication sendAction:to:from:] to implement a security guard against a known Use-After-Free (UAF) condition in AppKit’s auto-generated Dock-menu window list.

When a user right-clicks an application’s Dock icon, AppKit snapshots the window list to populate the menu. If a window is subsequently closed (e.g., via JavaScript) while the menu is still open, the menu continues to hold a raw pointer to the now-freed NSWindow. Selecting that window from the menu causes AppKit to call _selectWindow: on the freed object. BrowserCrApplication prevents this by verifying that the target window still exists in the application’s window list before dispatching the action.

AppShimApplication, the NSApplication subclass used by app shims (including Progressive Web Apps), lacks this override and the corresponding guard. Consequently, selecting a closed window from a PWA’s Dock menu results in a potential wild-pointer dispatch via objc_msgSend on the freed memory of a NativeWidgetMacNSWindow object.

Impact

The app shim process runs unsandboxed on macOS (Sandbox::kNoSandbox as defined in sandbox/policy/sandbox_type.cc). By reclaiming the memory of the freed NativeWidgetMacNSWindow with attacker-controlled data, an attacker could potentially gain control of the Objective-C isa pointer. This leads to a potential Remote Code Execution (RCE) primitive within the unsandboxed process, effectively allowing a compromise of the user environment from a PWA.

Potential Reproduction Steps

Note: These steps are based on source code analysis as our tooling does not yet have the ability to run functional exploits.

  1. Install a PWA in Chrome on macOS.
  2. In the PWA, open a popup window using let p = window.open(...).
  3. Right-click the PWA’s Dock icon to display the window list.
  4. While the menu is open, execute p.close() in the PWA. This causes the browser to send a Mojo message to the shim, which results in the destruction of the NativeWidgetNSWindowBridge and the deallocation of the corresponding NativeWidgetMacNSWindow object.
  5. Reclaim the freed memory in the shim process (e.g., by setting document.title on remaining windows to trigger allocations that may occupy the freed object’s memory slot).
  6. Select the stale popup window entry from the Dock menu.
  7. AppShimApplication will attempt to dispatch the _selectWindow: action to the freed/reclaimed object.

Recommendation

Implement the same sendAction:to:from: override in AppShimApplication (located in chrome/app_shim/app_shim_application.mm) as exists in BrowserCrApplication (chrome/browser/chrome_browser_application_mac.mm) to validate that the target of a _selectWindow: action is a valid window in the application’s window list.

Evaluated with Chrome root at commit: 1a8d40fc44df2088d5945c0bf53584038aa1614a


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