Overview

Low
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactIncorrect reference resolution in Core
DescriptionIncorrect reference resolution in Core
ComponentCore
Sub-componentInternals>Core
Bug ClassLogic Error
Tracker556211265
Fix commit3e7fc7921e3e (chromium/src) +1/-1
CISA KEVNot listed
CreditedGoogle
Disclosed2026-10-06

Changed Functions

FunctionChangeNotes
if
content/browser/web_contents/web_contents_impl.cc
modified

Files Changed

  • content/browser/web_contents/web_contents_impl.cc
From 3e7fc7921e3e0a3bf5d9a8d845f4bda5392ac0b0 Mon Sep 17 00:00:00 2001
From: Avi Drissman <avi@chromium.org>
Date: Fri, 04 Sep 2026 02:34:43 -0700
Subject: [PATCH] Don't resolve drags from inactive pages

It's possible that a page navigated after the drag started. In that
case, break the drag id lookup in order to cause the drop to fail.

Canceling the drag when the source navigates would be even better, but
that is OS-dependent and non-trivial, so we'll bump that to be a
feature request (https://crbug.com/556278698).

Fixed: 556211265
Bug: 556278698
Change-Id: Ia93513fad2f5d74666daaac58517db2c6a6a6964
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8344248
Auto-Submit: Avi Drissman <avi@chromium.org>
Reviewed-by: Arthur Sonzogni <arthursonzogni@chromium.org>
Commit-Queue: Arthur Sonzogni <arthursonzogni@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1692298}
---
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 20f1cd0..fdc17b7 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -862,7 +862,7 @@
   }
 
   RenderFrameHost* rfh = RenderFrameHost::FromFrameToken(source_rfh_token);
-  if (!rfh) {
+  if (!rfh || !rfh->IsActive()) {
     return nullptr;
   }
 
Loading diff…

Original Bug Report

reported by vm...@google.com

Glic context leak: BFCached drag source bypasses DragSourceDocumentTracker

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: When web content is dragged and dropped into the Glic panel, Chrome resolves the drag ID back to the source tab and extracts its current page context. If the source page navigates mid-drag into the Back/Forward Cache, DragSourceDocumentTracker persists and WebContents::FromDragId succeeds without checking the frame’s lifecycle state. This allows Glic to capture and upload the post-navigation page’s sensitive context misattributed to the pre-navigation URL.

Affected files:

  • content/browser/web_contents/web_contents_impl.cc
  • chrome/browser/glic/host/glic_drag_and_drop_util.cc
  • content/browser/web_contents/drag_source_document_tracker.h
  • content/browser/web_contents/drag_source_document_tracker.cc

Estimated timestamp from git blame: 2026-05-29

Summary

When a web drag is dropped into the Glic panel, Chrome resolves the internal drag ID back to the initiating tab to fetch its page context. If the initiating web page navigates mid-drag into the Back/Forward Cache (BFCache), DragSourceDocumentTracker and WebContents::FromDragId fail to invalidate the drag. As a result, Chrome extracts and ships the post-navigation page’s annotated text and title to the Glic service, attributed under the pre-navigation page’s URL.

Root Cause Analysis

  1. Drag Tracking Registration (content/browser/web_contents/web_contents_impl.cc:7995-8023): When a drag begins, WebContentsImpl::OnStartDragging generates a DragId, associates it with the document via DragSourceDocumentTracker::GetOrCreateForCurrentDocument(source_frame)->AddDragId(drag_id), and maps the ID to the frame’s GlobalRenderFrameHostToken in DragSourceMap.

  2. BFCache Persistence (content/public/browser/document_user_data.h:40-45): DragSourceDocumentTracker subclasses DocumentUserData. When a document transitions into the Back/Forward Cache upon navigation, its DocumentUserData instances are intentionally preserved. Consequently, ~DragSourceDocumentTracker does not run, and the DragSourceMap entry is not removed.

  3. Missing Lifecycle State Validation in WebContents::FromDragId (content/browser/web_contents/web_contents_impl.cc:856-874):

    WebContents* WebContents::FromDragId(BrowserContext* browser_context,
                                         const DragId& drag_id) {
      auto* map = DragSourceMap::GetOrCreate(browser_context);
      GlobalRenderFrameHostToken source_rfh_token = map->GetDragSource(drag_id);
      ...
      RenderFrameHost* rfh = RenderFrameHost::FromFrameToken(source_rfh_token);
      if (!rfh) return nullptr;
    
      auto* tracker = DragSourceDocumentTracker::GetForCurrentDocument(rfh);
      if (!tracker || !tracker->has_drag_id(drag_id)) return nullptr;
    
      return WebContents::FromRenderFrameHost(rfh);
    }
    

    RenderFrameHost::FromFrameToken retrieves the BFCached RenderFrameHostImpl from GetTokenFrameMap(). FromDragId verifies the tracker and returns the tab’s WebContents without checking whether rfh is active (rfh->IsActive()).

  4. Context Extraction on the Wrong Document (chrome/browser/glic/host/glic_drag_and_drop_util.cc:303-341): In StartDragAndDropInvoke, source_wc->GetPrimaryMainFrame() is called on the resolved WebContents. Because the tab navigated, this returns the new primary document (e.g., a victim page), not the original initiating document. FetchPageContext is then invoked on the active tab, capturing the post-navigation page’s annotated content and bundling it with the pre-navigation URL in BuildDragDropAdditionalContext (...:75-77).

Potential Reproduction Steps

(Note: These are suggested theoretical steps based on static code analysis; our automated tooling does not currently possess live execution capabilities.)

  1. Enable the Glic UI panel alongside the main browser window (feature features::kGlicWebDragAndDropFileUpload is enabled by default).
  2. Load an attacker page https://attacker.example/ that renders a draggable element and is eligible for BFCache (no unload listener, cacheable headers).
  3. In the page’s dragstart event listener, initiate a navigation via location.href = 'https://victim.example/account' or history.back().
  4. Drag the element toward the Glic panel. The OS drag loop pumps nested application tasks, allowing the navigation to commit while the drag gesture is in flight.
  5. Drop the element onto the Glic panel.
  6. Observe that HandleOnPerformingDrop -> StartDragAndDropInvoke succeeds, and Glic receives the annotated page context of https://victim.example/account attributed to https://attacker.example/.

Impact

An attacker-controlled web page can induce Chrome to capture the full semantic text and metadata of a cross-origin, authenticated page that the user never intended to share with Glic, misattributed under the attacker’s URL. The destination sink is the trusted Glic service/backend under the user’s account.

Suggested Fix

  1. In WebContents::FromDragId (content/browser/web_contents/web_contents_impl.cc:864-874), enforce that the resolved RenderFrameHost is currently active before returning:
    if (!rfh || !rfh->IsActive()) {
      return nullptr;
    }
    
  2. In chrome/browser/glic/host/glic_drag_and_drop_util.cc, verify that source_wc->GetPrimaryMainFrame() matches the initiating RenderFrameHost or its WeakDocumentPtr before invoking FetchPageContext.

Evaluated with Chrome root at commit: 53c437ac4ea52cc89d0265eb9e6d68666fdb303e


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