CVE-2026-11093
Overview
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifchrome/browser/printing/print_view_manager.cc |
modified |
Files Changed
chrome/browser/printing/print_view_manager.cc
Patch
From 4db1b010ed2fc123c156dd64fa86e68a368298f6 Mon Sep 17 00:00:00 2001 From: Lei Zhang <[email protected]> Date: Mon, 13 Apr 2026 13:45:32 -0700 Subject: [PATCH] Printing: Check for inactive RFHs when handing print preview requests Since only active RFHs should show UI elements, reject print preview requests from inactive RFHs in PrintViewManager::OnRequestPrintPreviewCallback(). Bug: 500172365 Change-Id: I172ee84827ccff36eed0414c8b235d7c83185512 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7745032 Reviewed-by: Daniel Cheng <[email protected]> Commit-Queue: Lei Zhang <[email protected]> Cr-Commit-Position: refs/heads/main@{#1613951} --- diff --git a/chrome/browser/printing/print_view_manager.cc b/chrome/browser/printing/print_view_manager.cc index 0b436fd40..83992e7 100644 --- a/chrome/browser/printing/print_view_manager.cc +++ b/chrome/browser/printing/print_view_manager.cc @@ -448,11 +448,18 @@ // Double-check that the RenderFrameHost is still alive and has a live // RenderFrame, since the DLP check is potentially asynchronous. auto* render_frame_host = content::RenderFrameHost::FromID(rfh_id); - if (!render_frame_host || !render_frame_host->IsRenderFrameLive()) + if (!render_frame_host || !render_frame_host->IsRenderFrameLive()) { return; + } - if (params->webnode_only) + // Also check it is active. Only active RFHs should show UI elements. + if (!render_frame_host->IsActive()) { + return; + } + + if (params->webnode_only) { PrintPreviewForWebNode(render_frame_host); + } auto* dialog_controller = PrintPreviewDialogController::GetInstance(); CHECK(dialog_controller);
Original Bug Report
UI Spoofing and Cross-Origin URL Leak via Missing IsActive Check in PrintViewManager
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: PrintViewManager::RequestPrintPreview processes IPCs from frames in the Back-Forward Cache (BFCache) because it fails to verify if the frame is active. A compromised renderer can send this IPC after a cross-origin navigation, triggering a print dialog over the new page and causing the browser to leak the new page’s URL and title back to the cached attacker frame.
Affected files:
chrome/browser/printing/print_view_manager.ccchrome/browser/ui/webui/print_preview/print_preview_handler.cc
Estimated timestamp from git blame: 2022-02-25
Summary
PrintViewManager::RequestPrintPreview and its callback OnRequestPrintPreviewCallback in the browser process lack a crucial check to ensure that the requesting RenderFrameHost (RFH) is currently active. This oversight allows a compromised renderer that has entered the Back-Forward Cache (BFCache) to send IPCs that trigger a print preview dialog over the user’s current, unrelated page. Furthermore, the print preview system inadvertently fetches the URL and title of the new page and sends this sensitive data back to the attacker’s cached frame.
Vulnerability Details
- Missing
IsActive()Check: Inchrome/browser/printing/print_view_manager.cc, theRequestPrintPreviewmethod processes theprinting.mojom.PrintManagerHostinterface. The callbackOnRequestPrintPreviewCallbackverifies the sender using!render_frame_host || !render_frame_host->IsRenderFrameLive(). However, frames in the BFCache are considered “live” but not active. The code fails to callrender_frame_host->IsActive(), allowing the request to proceed. - Receiver Persistence: The
content::RenderFrameHostReceiverSetmanaging thePrintManagerHostinterface only removes receivers whenRenderFrameDeletedis called. Since entering the BFCache does not delete the frame, the interface remains fully bound and capable of receiving messages from a malicious renderer. - State Corruption and UI Spoofing: If the attacker sends
RequestPrintPreview({webnode_only: true})from the BFCache,PrintPreviewForWebNode(render_frame_host)is called. This sets thePrintViewManager’sprint_preview_rfh_pointer to the attacker’s inactive frame. The browser then opens a tab-modal print preview dialog over the currentWebContents(which now displays a new, cross-origin page), resulting in UI spoofing. - Cross-Origin Information Leak: When the
chrome://printWebUI initializes, it requests preview data. Inchrome/browser/ui/webui/print_preview/print_preview_handler.cc,PrintPreviewHandler::HandleGetPreviewidentifies the initiatorWebContents(the current tab) and reads its title and URL (initiator->GetTitle()andinitiator->GetLastCommittedURL()). Becauseprint_preview_rfh_was set to the attacker’s frame in step 3, the handler binds aPrintRenderFrameremote to the attacker’s BFCached frame and sends aPrintPreviewIPC containing the victim’s URL and title. The attacker’s renderer intercepts this IPC to steal the data.
Impact
- Cross-Origin Information Leak: An attacker can silently obtain the URL and title of the page the user navigated to after leaving the attacker-controlled site.
- UI Spoofing: An attacker can display a tab-modal print dialog over an unrelated, sensitive origin, potentially causing confusion or facilitating further spoofing attacks.
Potential Reproduction Steps
(Note: These are suggested steps based on code analysis; our tooling agent cannot execute code to verify.)
- A user navigates to an attacker-controlled site.
- The attacker achieves code execution in the renderer process (e.g., via a separate V8 bug) and binds the
printing.mojom.PrintManagerHostinterface. - The user navigates to a sensitive “victim” site within the same tab. The attacker’s page enters the BFCache.
- While in the BFCache, the compromised attacker renderer sends a
RequestPrintPreviewIPC withparams->webnode_onlyset totrue. - A print preview dialog unexpectedly appears over the victim site.
- The attacker renderer intercepts the incoming
PrintPreviewIPC and extracts the victim site’s title and URL.
Suggested Fix
Add an IsActive() check to PrintViewManager::OnRequestPrintPreviewCallback:
auto* render_frame_host = content::RenderFrameHost::FromID(rfh_id);
if (!render_frame_host || !render_frame_host->IsRenderFrameLive() ||
!render_frame_host->IsActive())
return;
Other printing IPCs (like SetupScriptedPrintPreview) correctly implement this active check.
Evaluated with Chrome root at commit: f200f57a19490707ff8bc7aa5de3cbc443a3afad
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.