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( ...@@ -2695,8 +2695,7 @@ void WebContentsImpl::CreateNewWindow(
// Any new WebContents opened while this WebContents is in fullscreen can be // Any new WebContents opened while this WebContents is in fullscreen can be
// used to confuse the user, so drop fullscreen. // used to confuse the user, so drop fullscreen.
if (IsFullscreenForCurrentTab()) ForSecurityDropFullscreen();
ExitFullscreen(true);
if (params.opener_suppressed) { if (params.opener_suppressed) {
// When the opener is suppressed, the original renderer cannot access the // When the opener is suppressed, the original renderer cannot access the
...@@ -4366,8 +4365,7 @@ void WebContentsImpl::ViewSource(RenderFrameHostImpl* frame) { ...@@ -4366,8 +4365,7 @@ void WebContentsImpl::ViewSource(RenderFrameHostImpl* frame) {
// Any new WebContents opened while this WebContents is in fullscreen can be // Any new WebContents opened while this WebContents is in fullscreen can be
// used to confuse the user, so drop fullscreen. // used to confuse the user, so drop fullscreen.
if (IsFullscreenForCurrentTab()) ForSecurityDropFullscreen();
ExitFullscreen(true);
// We intentionally don't share the SiteInstance with the original frame so // 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 // 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, ...@@ -5078,8 +5076,7 @@ void WebContentsImpl::RunJavaScriptDialog(RenderFrameHost* render_frame_host,
// Running a dialog causes an exit to webpage-initiated fullscreen. // Running a dialog causes an exit to webpage-initiated fullscreen.
// http://crbug.com/728276 // http://crbug.com/728276
if (IsFullscreenForCurrentTab()) ForSecurityDropFullscreen();
ExitFullscreen(true);
auto callback = auto callback =
base::BindOnce(&WebContentsImpl::OnDialogClosed, base::Unretained(this), base::BindOnce(&WebContentsImpl::OnDialogClosed, base::Unretained(this),
...@@ -5148,8 +5145,7 @@ void WebContentsImpl::RunBeforeUnloadConfirm( ...@@ -5148,8 +5145,7 @@ void WebContentsImpl::RunBeforeUnloadConfirm(
// Running a dialog causes an exit to webpage-initiated fullscreen. // Running a dialog causes an exit to webpage-initiated fullscreen.
// http://crbug.com/728276 // http://crbug.com/728276
if (IsFullscreenForCurrentTab()) ForSecurityDropFullscreen();
ExitFullscreen(true);
RenderFrameHostImpl* rfhi = RenderFrameHostImpl* rfhi =
static_cast<RenderFrameHostImpl*>(render_frame_host); static_cast<RenderFrameHostImpl*>(render_frame_host);
...@@ -5731,6 +5727,15 @@ void WebContentsImpl::EnsureOpenerProxiesExist(RenderFrameHost* source_rfh) { ...@@ -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() { void WebContentsImpl::SetAsFocusedWebContentsIfNecessary() {
// Only change focus if we are not currently focused. // Only change focus if we are not currently focused.
WebContentsImpl* old_contents = GetFocusedWebContents(); WebContentsImpl* old_contents = GetFocusedWebContents();
...@@ -5798,8 +5803,7 @@ void WebContentsImpl::SetFocusedFrame(FrameTreeNode* node, ...@@ -5798,8 +5803,7 @@ void WebContentsImpl::SetFocusedFrame(FrameTreeNode* node,
void WebContentsImpl::DidCallFocus() { void WebContentsImpl::DidCallFocus() {
// Any explicit focusing of another window while this WebContents is in // Any explicit focusing of another window while this WebContents is in
// fullscreen can be used to confuse the user, so drop fullscreen. // fullscreen can be used to confuse the user, so drop fullscreen.
if (IsFullscreenForCurrentTab()) ForSecurityDropFullscreen();
ExitFullscreen(true);
} }
RenderFrameHost* WebContentsImpl::GetFocusedFrameIncludingInnerWebContents() { RenderFrameHost* WebContentsImpl::GetFocusedFrameIncludingInnerWebContents() {
......
...@@ -926,6 +926,11 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents, ...@@ -926,6 +926,11 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
// |IsFullscreen| must return |true| when this method is called. // |IsFullscreen| must return |true| when this method is called.
bool IsPictureInPictureAllowedForFullscreenVideo() const; 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 // When inner or outer WebContents are present, become the focused
// WebContentsImpl. This will activate this content's main frame RenderWidget // WebContentsImpl. This will activate this content's main frame RenderWidget
// and indirectly all its subframe widgets. GetFocusedRenderWidgetHost will // and indirectly all its subframe widgets. GetFocusedRenderWidgetHost will
...@@ -1016,6 +1021,8 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents, ...@@ -1016,6 +1021,8 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
JavaScriptDialogsInMainAndSubframes); JavaScriptDialogsInMainAndSubframes);
FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest, FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest,
DialogsFromJavaScriptEndFullscreen); DialogsFromJavaScriptEndFullscreen);
FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest,
DialogsFromJavaScriptEndFullscreenEvenInInnerWC);
FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest, FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest,
PopupsFromJavaScriptEndFullscreen); PopupsFromJavaScriptEndFullscreen);
FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest, FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest,
......
...@@ -2132,6 +2132,51 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, ...@@ -2132,6 +2132,51 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
wc->SetJavaScriptDialogManagerForTesting(nullptr); 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, IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
PopupsFromJavaScriptEndFullscreen) { PopupsFromJavaScriptEndFullscreen) {
WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell()->web_contents()); 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