0

Prevent new windows/popups etc via OpenURL while prerendering

With this change, if we call OpenURL while prerendering and the
window disposition is anything other than CURRENT_TAB, the call will
fail.

Bug: 1211053
Change-Id: I2844141e5db614d4fdfe02169b30026a96e594cf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2907272
Commit-Queue: Ian Vollick <vollick@chromium.org>
Reviewed-by: Matt Falkenhagen <falken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#885014}
This commit is contained in:
Ian Vollick
2021-05-20 14:21:30 +00:00
committed by Chromium LUCI CQ
parent 844e36772b
commit f6725a2e23
2 changed files with 42 additions and 2 deletions
content/browser

@ -834,6 +834,38 @@ IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, ActivatePageWithInnerContents) {
EXPECT_EQ(GetRequestCount(kInnerContentsUrl), 1);
}
// Ensures that if we attempt to open a URL while prerendering with a window
// disposition other than CURRENT_TAB, we
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, SuppressOpenURL) {
const GURL kInitialUrl = GetUrl("/prerender/add_prerender.html");
const GURL kPrerenderingUrl = GetUrl("/empty.html");
const GURL kSecondUrl = GetUrl("/title1.html");
// Navigate to an initial page.
ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
ASSERT_EQ(web_contents()->GetURL(), kInitialUrl);
// Add <link rel=prerender> that will prerender `kPrerenderingUrl`.
ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 0);
const int host_id = AddPrerender(kPrerenderingUrl);
RenderFrameHostImpl* prerendered_render_frame_host =
GetPrerenderedMainFrameHost(host_id);
EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
auto* web_contents =
WebContents::FromRenderFrameHost(prerendered_render_frame_host);
OpenURLParams params(kSecondUrl, Referrer(),
prerendered_render_frame_host->GetFrameTreeNodeId(),
WindowOpenDisposition::NEW_WINDOW,
ui::PAGE_TRANSITION_LINK, true);
params.initiator_origin =
prerendered_render_frame_host->GetLastCommittedOrigin();
params.source_render_process_id =
prerendered_render_frame_host->GetProcess()->GetID();
params.source_render_frame_id = prerendered_render_frame_host->GetRoutingID();
auto* new_web_contents = web_contents->OpenURL(params);
EXPECT_EQ(nullptr, new_web_contents);
}
// Tests that |RenderFrameHost::ForEachRenderFrameHost| and
// |WebContents::ForEachRenderFrameHost| behave correctly when prerendering.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, ForEachRenderFrameHost) {

@ -182,6 +182,7 @@
#include "ui/accessibility/ax_tree_combiner.h"
#include "ui/base/device_form_factor.h"
#include "ui/base/dragdrop/mojom/drag_drop_types.mojom.h"
#include "ui/base/window_open_disposition.h"
#if defined(USE_AURA)
#include "ui/aura/window.h"
#endif
@ -4428,11 +4429,18 @@ WebContents* WebContentsImpl::OpenURL(const OpenURLParams& params) {
return nullptr;
}
WebContents* new_contents = delegate_->OpenURLFromTab(this, params);
RenderFrameHost* source_render_frame_host = RenderFrameHost::FromID(
params.source_render_process_id, params.source_render_frame_id);
// Prevent frams that are not active from opening new windows, tabs, popups,
// etc.
if (params.disposition != WindowOpenDisposition::CURRENT_TAB &&
source_render_frame_host && !source_render_frame_host->IsCurrent()) {
return nullptr;
}
WebContents* new_contents = delegate_->OpenURLFromTab(this, params);
if (source_render_frame_host && params.source_site_instance) {
CHECK_EQ(source_render_frame_host->GetSiteInstance(),
params.source_site_instance.get());