Medium chrome Logic Error 📄 Reporter bug report 🔧 Commit mapped

Overview

Medium
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactInsufficient validation of untrusted input in Printing
DescriptionInsufficient validation of untrusted input in Printing
ComponentPrinting
Bug ClassLogic Error
Tracker500172365
Fix commit4db1b010ed2f (chromium/src) +9/-2
CISA KEVNot listed
CreditedGoogle
Disclosed2026-06-02

Changed Functions

FunctionChangeNotes
if
chrome/browser/printing/print_view_manager.cc
modified

Files Changed

  • chrome/browser/printing/print_view_manager.cc
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);
Loading diff…

Original Bug Report

reported by [email protected]

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.cc
  • chrome/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

  1. Missing IsActive() Check: In chrome/browser/printing/print_view_manager.cc, the RequestPrintPreview method processes the printing.mojom.PrintManagerHost interface. The callback OnRequestPrintPreviewCallback verifies 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 call render_frame_host->IsActive(), allowing the request to proceed.
  2. Receiver Persistence: The content::RenderFrameHostReceiverSet managing the PrintManagerHost interface only removes receivers when RenderFrameDeleted is called. Since entering the BFCache does not delete the frame, the interface remains fully bound and capable of receiving messages from a malicious renderer.
  3. State Corruption and UI Spoofing: If the attacker sends RequestPrintPreview({webnode_only: true}) from the BFCache, PrintPreviewForWebNode(render_frame_host) is called. This sets the PrintViewManager’s print_preview_rfh_ pointer to the attacker’s inactive frame. The browser then opens a tab-modal print preview dialog over the current WebContents (which now displays a new, cross-origin page), resulting in UI spoofing.
  4. Cross-Origin Information Leak: When the chrome://print WebUI initializes, it requests preview data. In chrome/browser/ui/webui/print_preview/print_preview_handler.cc, PrintPreviewHandler::HandleGetPreview identifies the initiator WebContents (the current tab) and reads its title and URL (initiator->GetTitle() and initiator->GetLastCommittedURL()). Because print_preview_rfh_ was set to the attacker’s frame in step 3, the handler binds a PrintRenderFrame remote to the attacker’s BFCached frame and sends a PrintPreview IPC 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.)

  1. A user navigates to an attacker-controlled site.
  2. The attacker achieves code execution in the renderer process (e.g., via a separate V8 bug) and binds the printing.mojom.PrintManagerHost interface.
  3. The user navigates to a sensitive “victim” site within the same tab. The attacker’s page enters the BFCache.
  4. While in the BFCache, the compromised attacker renderer sends a RequestPrintPreview IPC with params->webnode_only set to true.
  5. A print preview dialog unexpectedly appears over the victim site.
  6. The attacker renderer intercepts the incoming PrintPreview IPC 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.

View on issue tracker