CVE-2026-95296
Overview
Background
- `DropData`
- the browser-side struct describing content being dragged into a
WebContents, includingfile_contentswhich can carry the raw bytes of a dragged image file. - `_dragSecurityInfo`
- a per-drag security context in
web_drag_dest_mac.mmwhoseIsImageAccessibleFromFrame()reports whether the target frame is actually allowed to read the dragged image’s contents (e.g. respecting cross-origin restrictions). - `FilterDropData`
- a
RenderWidgetHostmethod that sanitizes aDropDataagainst the target renderer, but which does not by itself strip imagefile_contentsbased on frame-level image accessibility. - `WebContentsViewAura`
- the non-Mac drag implementation that already consulted the drag security info before attaching file data, establishing the invariant the Mac path failed to honor.
Root Cause Analysis
On the Mac drag path in web_drag_dest_mac.mm, a DropData was built from _dropDataUnfiltered and passed through FilterDropData, but the result was delivered to the renderer without ever consulting _dragSecurityInfo.IsImageAccessibleFromFrame(). The Aura (non-Mac) implementation in WebContentsViewAura already gated the inclusion of file data on this security check, so the Mac code violated the invariant that image file_contents must only be exposed to a frame permitted to access the image. Because the Mac attachment of file data happens at a stage that does not allow the same in-place check, the unfiltered image bytes could be handed to a frame that should not read them.
The fix adds, at both the drag-entry and cached-filtering sites, an explicit check that resizes dropData->file_contents to zero whenever IsImageAccessibleFromFrame() returns false, restoring parity with the Aura path and re-establishing the authorization boundary before the data reaches the renderer.
file_contents to unauthorized frames; the fix reinstates that check by clearing file_contents when _dragSecurityInfo.IsImageAccessibleFromFrame() is false.Attack Path
- Set up a cross-origin image drag An attacker page arranges a drag involving an image whose bytes the target frame is not authorized to read (a cross-origin image the frame can display but not extract).
- Trigger the Mac drag path
On macOS, the drag enters
web_drag_dest_mac.mm, which constructs aDropDatafrom_dropDataUnfilteredand runsFilterDropDatabut omits the image-accessibility check. - Deliver unfiltered file contents
Because
IsImageAccessibleFromFrame()was never consulted, the raw imagefile_contentsremain populated in theDropDatahanded to the renderer. - Exfiltrate the image bytes (inferred)
The receiving frame reads the leaked
file_contentsit should not have had access to, disclosing cross-origin image data.
Impact Assessment
file_contents; any broader escalation beyond this disclosure is (inferred). The advisory classifies this as a missing-authorization logic error in Core and states no exploited-in-the-wild status.Files Changed
content/browser/web_contents/web_drag_dest_mac.mm
Audit Directions
- Platform parity of security checksAudit every platform-specific drag/paste/clipboard implementation (Mac, Aura, Android) to confirm each independently enforces the same authorization checks, since one path (Aura) had the check while another (Mac) silently omitted it.
- `file_contents` handlingTrace all producers and consumers of
DropData::file_contentsto ensure image bytes are stripped wheneverIsImageAccessibleFromFrame()(or equivalent frame-access predicates) would deny access. - Post-filter data injectionLook for cases where data is added to a
DropDataafterFilterDropDataruns, or at a stage that bypasses the standard filtering, so that late-attached content escapes authorization enforcement.
Patch
From f339249dd4910c22f6e71aeb15826c510bc40914 Mon Sep 17 00:00:00 2001 From: Avi Drissman <[email protected]> Date: Mon, 31 Aug 2026 12:48:56 -0700 Subject: [PATCH] Obey security info for drags on the Mac WebContentsViewAura checks the security info for the drag before adding file data onto the drag. For the Mac side, the addition of file data happens at a time that doesn't allow for that, so filter the drag before delivering the data. Fixed: 551296612 Change-Id: I00d5ea282efb763ba03ae0b27cb584016a6a6964 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8299555 Reviewed-by: Joel Hockey <[email protected]> Commit-Queue: Avi Drissman <[email protected]> Cr-Commit-Position: refs/heads/main@{#1689168} --- diff --git a/content/browser/web_contents/web_drag_dest_mac.mm b/content/browser/web_contents/web_drag_dest_mac.mm index 160026b..a62d340 100644 --- a/content/browser/web_contents/web_drag_dest_mac.mm +++ b/content/browser/web_contents/web_drag_dest_mac.mm @@ -333,6 +333,9 @@ std::make_unique<DropData>(*_dropDataUnfiltered); _currentRWHForDrag = targetRWH->GetWeakPtr(); _currentRWHForDrag->FilterDropData(dropData.get()); + if (!_dragSecurityInfo.IsImageAccessibleFromFrame()) { + dropData->file_contents.resize(0); + } NSDragOperation mask = info->operation_mask; @@ -663,6 +666,9 @@ std::unique_ptr<DropData> dropData = std::make_unique<DropData>(*_dropDataUnfiltered); targetRWH->FilterDropData(dropData.get()); + if (!_dragSecurityInfo.IsImageAccessibleFromFrame()) { + dropData->file_contents.resize(0); + } _dropDataFiltered.swap(dropData); }