CVE-2026-8584
Overview
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifui/views/widget/desktop_aura/desktop_drag_drop_client_win.cc |
modified |
Files Changed
ui/views/widget/desktop_aura/desktop_drag_drop_client_win.cc
Patch
From 6d737c5ce20ffa451419440fb52e617d9351fbf7 Mon Sep 17 00:00:00 2001 From: David Bienvenu <[email protected]> Date: Fri, 03 Apr 2026 11:19:37 -0700 Subject: [PATCH] win: Guard against drag reentrancy Use CHECK to protect against drag reentrancy. Bug: 498892595 Change-Id: I87cd36e6844c9e28db4d3d232c9dd8ab04412f11 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7726485 Reviewed-by: Robert Liao <[email protected]> Commit-Queue: David Bienvenu <[email protected]> Cr-Commit-Position: refs/heads/main@{#1609873} --- diff --git a/ui/views/widget/desktop_aura/desktop_drag_drop_client_win.cc b/ui/views/widget/desktop_aura/desktop_drag_drop_client_win.cc index 8aeee53..b096048e 100644 --- a/ui/views/widget/desktop_aura/desktop_drag_drop_client_win.cc +++ b/ui/views/widget/desktop_aura/desktop_drag_drop_client_win.cc @@ -71,6 +71,7 @@ const gfx::Point& screen_location, int allowed_operations, ui::mojom::DragEventSource source) { + CHECK(!drag_drop_in_progress_); gfx::Point touch_screen_point; if (source == ui::mojom::DragEventSource::kTouch) { source_window->GetHost()->ConvertDIPToPixels(&touch_screen_point);
Original Bug Report
Potential Reentrancy in Windows Drag-and-Drop allows UI Spoofing/Arbitrary Data Drop
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 without the security team.
Overview: The Windows implementation of drag-and-drop lacks a reentrancy guard. A compromised renderer can initiate a second, nested drag-and-drop operation while a first is already in progress, manipulating the OS cursor and dropping arbitrary data (like javascript: URLs) onto targeted overlapping applications or browser UI.
Affected files:
ui/views/widget/desktop_aura/desktop_drag_drop_client_win.ccui/views/widget/desktop_aura/desktop_window_tree_host_win.cccontent/browser/web_contents/web_contents_view_aura.cc
Estimated timestamp from git blame: 2025-08-20
Summary
A lack of state validation in DesktopDragDropClientWin::StartDragAndDrop allows a compromised renderer to trigger a nested, reentrant native drag-and-drop loop. This allows an attacker to bypass security checks that ensure the user is actively touching the screen, forcibly move the OS cursor, and execute a data ‘drop’ (including javascript: URLs) at an attacker-controlled screen coordinate that overlaps with the browser’s web bounds.
Technical Details
When a touch-based drag-and-drop is initiated by a web page, the browser calls DesktopDragDropClientWin::StartDragAndDrop. This function checks aura::Env::GetInstance()->is_touch_down() and verifies the cursor is over the source window. It then calls DesktopWindowTreeHostWin::StartTouchDrag(location), which uses the Windows ::SendInput API to forcibly move the OS cursor to the specified location. Finally, it enters the native ::DoDragDrop message loop, which is a blocking, nested run loop.
Critically, WebContentsViewAura::StartDragging instantiates base::CurrentThread::ScopedAllowApplicationTasksInNativeNestedLoop before calling this. This means that while blocked in ::DoDragDrop, the browser UI thread can still process incoming Mojo IPC messages.
Because DesktopDragDropClientWin::StartDragAndDrop does not check if drag_drop_in_progress_ is already true (unlike Ash, which explicitly blocks reentrancy), a compromised renderer can exploit this:
- The attacker (e.g., via a compromised renderer with an OOPIF) sends a
LocalFrameHost::StartDraggingIPC to start a touch drag at a safe coordinateP_safe. The browser enters the::DoDragDroploop and moves the OS cursor toP_safe. - While blocked in
::DoDragDrop, touch release events are intercepted and not dispatched toWindowEventDispatcher. Consequently, the globalis_touch_down()state freezes astrue. - The attacker sends a second
LocalFrameHost::StartDraggingIPC specifying a target locationP_victim(a coordinate within the WebContents bounds, but potentially overlapping a sensitive UI element like the bookmarks bar or another window). - The browser processes this second IPC reentrantly. The frozen
is_touch_down()state and the current OS cursor position (P_safe) satisfy the security checks in the nestedStartDragAndDropcall. StartTouchDrag(P_victim)is called, forcibly moving the OS cursor toP_victimusing::SendInput.- The nested
::DoDragDropfails immediately (Windows OLE disallows nested loops on the same thread). The cleanup code synthesizes aLEFTUPmouse event atP_victim. - The outer
::DoDragDroploop receives thisLEFTUPevent, interprets it as a user drop at the new cursor location (P_victim), and drops the attacker’s payload (e.g., ajavascript:URL).
Impact
An attacker can drop arbitrary payload data (like javascript: URLs, which bypass the FilterURL check specifically to allow bookmarklets) onto any UI element or application that overlaps the WebContents bounds. This can lead to UXSS (saving a malicious bookmarklet) or dropping data onto an overlapping native application.
Proposed Fix
Add a reentrancy guard to DesktopDragDropClientWin::StartDragAndDrop. Similar to Ash’s DragDropController, it should check if a drag is already active and return early:
if (drag_drop_in_progress_) {
return ui::PreferredDragOperation(
ui::DragDropTypes::DropEffectToDragOperation(DROPEFFECT_NONE));
}
Evaluated with Chrome root at commit: ff3d2b74fa39431785bd60e51463b08fcc71ee33
Results so far have been promising, but there can be wrong deductions. If this proves to be a false positive, please close as WAI; 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.