Commit 3dcaec6e authored by Avi Drissman's avatar Avi Drissman Committed by Commit Bot

Security drop fullscreen for any nested WebContents level.

BUG=873080
TEST=as in bug

Change-Id: Icd75715ac42789c84870967b11c9917a972ae086
Reviewed-on: https://chromium-review.googlesource.com/1173342
Commit-Queue: Avi Drissman <avi@chromium.org>
Reviewed-by: default avatarSidney San Martín <sdy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#582970}
parent 1f548335
......@@ -2695,8 +2695,7 @@ void WebContentsImpl::CreateNewWindow(
// Any new WebContents opened while this WebContents is in fullscreen can be
// used to confuse the user, so drop fullscreen.
if (IsFullscreenForCurrentTab())
ExitFullscreen(true);
ForSecurityDropFullscreen();
if (params.opener_suppressed) {
// When the opener is suppressed, the original renderer cannot access the
......@@ -4366,8 +4365,7 @@ void WebContentsImpl::ViewSource(RenderFrameHostImpl* frame) {
// Any new WebContents opened while this WebContents is in fullscreen can be
// used to confuse the user, so drop fullscreen.
if (IsFullscreenForCurrentTab())
ExitFullscreen(true);
ForSecurityDropFullscreen();
// We intentionally don't share the SiteInstance with the original frame so
// that view source has a consistent process model and always ends up in a new
......@@ -5078,8 +5076,7 @@ void WebContentsImpl::RunJavaScriptDialog(RenderFrameHost* render_frame_host,
// Running a dialog causes an exit to webpage-initiated fullscreen.
// http://crbug.com/728276
if (IsFullscreenForCurrentTab())
ExitFullscreen(true);
ForSecurityDropFullscreen();
auto callback =
base::BindOnce(&WebContentsImpl::OnDialogClosed, base::Unretained(this),
......@@ -5148,8 +5145,7 @@ void WebContentsImpl::RunBeforeUnloadConfirm(
// Running a dialog causes an exit to webpage-initiated fullscreen.
// http://crbug.com/728276
if (IsFullscreenForCurrentTab())
ExitFullscreen(true);
ForSecurityDropFullscreen();
RenderFrameHostImpl* rfhi =
static_cast<RenderFrameHostImpl*>(render_frame_host);
......@@ -5731,6 +5727,15 @@ void WebContentsImpl::EnsureOpenerProxiesExist(RenderFrameHost* source_rfh) {
}
}
void WebContentsImpl::ForSecurityDropFullscreen() {
WebContentsImpl* web_contents = this;
while (web_contents) {
if (web_contents->IsFullscreenForCurrentTab())
web_contents->ExitFullscreen(true);
web_contents = web_contents->GetOuterWebContents();
}
}
void WebContentsImpl::SetAsFocusedWebContentsIfNecessary() {
// Only change focus if we are not currently focused.
WebContentsImpl* old_contents = GetFocusedWebContents();
......@@ -5798,8 +5803,7 @@ void WebContentsImpl::SetFocusedFrame(FrameTreeNode* node,
void WebContentsImpl::DidCallFocus() {
// Any explicit focusing of another window while this WebContents is in
// fullscreen can be used to confuse the user, so drop fullscreen.
if (IsFullscreenForCurrentTab())
ExitFullscreen(true);
ForSecurityDropFullscreen();
}
RenderFrameHost* WebContentsImpl::GetFocusedFrameIncludingInnerWebContents() {
......
......@@ -926,6 +926,11 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
// |IsFullscreen| must return |true| when this method is called.
bool IsPictureInPictureAllowedForFullscreenVideo() const;
// The WebContents is trying to take some action that would cause user
// confusion if taken while in fullscreen. If this WebContents or any outer
// WebContents is in fullscreen, drop it.
void ForSecurityDropFullscreen();
// When inner or outer WebContents are present, become the focused
// WebContentsImpl. This will activate this content's main frame RenderWidget
// and indirectly all its subframe widgets. GetFocusedRenderWidgetHost will
......@@ -1016,6 +1021,8 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
JavaScriptDialogsInMainAndSubframes);
FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest,
DialogsFromJavaScriptEndFullscreen);
FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest,
DialogsFromJavaScriptEndFullscreenEvenInInnerWC);
FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest,
PopupsFromJavaScriptEndFullscreen);
FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest,
......
......@@ -2132,6 +2132,51 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
wc->SetJavaScriptDialogManagerForTesting(nullptr);
}
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
DialogsFromJavaScriptEndFullscreenEvenInInnerWC) {
WebContentsImpl* top_contents =
static_cast<WebContentsImpl*>(shell()->web_contents());
TestWCDelegateForDialogsAndFullscreen top_test_delegate;
top_contents->SetDelegate(&top_test_delegate);
GURL url("about:blank");
EXPECT_TRUE(NavigateToURL(shell(), url));
FrameTreeNode* root = top_contents->GetFrameTree()->root();
ASSERT_EQ(0U, root->child_count());
std::string script =
"var iframe = document.createElement('iframe');"
"document.body.appendChild(iframe);";
EXPECT_TRUE(content::ExecuteScript(root->current_frame_host(), script));
EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
ASSERT_EQ(1U, root->child_count());
RenderFrameHost* frame = root->child_at(0)->current_frame_host();
ASSERT_NE(nullptr, frame);
WebContentsImpl* inner_contents =
static_cast<WebContentsImpl*>(CreateAndAttachInnerContents(frame));
TestWCDelegateForDialogsAndFullscreen inner_test_delegate;
inner_contents->SetDelegate(&inner_test_delegate);
// A dialog from the inner WebContents should make the outer contents lose
// fullscreen.
top_contents->EnterFullscreenMode(url, blink::WebFullscreenOptions());
EXPECT_TRUE(top_contents->IsFullscreenForCurrentTab());
script = "alert('hi')";
inner_test_delegate.WillWaitForDialog();
EXPECT_TRUE(content::ExecuteScript(inner_contents, script));
inner_test_delegate.Wait();
EXPECT_FALSE(top_contents->IsFullscreenForCurrentTab());
inner_contents->SetDelegate(nullptr);
inner_contents->SetJavaScriptDialogManagerForTesting(nullptr);
top_contents->SetDelegate(nullptr);
top_contents->SetJavaScriptDialogManagerForTesting(nullptr);
}
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
PopupsFromJavaScriptEndFullscreen) {
WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell()->web_contents());
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment