diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-10-14 14:23:40 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-10-16 09:04:55 +0000 |
commit | b1ce3367b4895c1f57de79ef081f4b7bbaa011f8 (patch) | |
tree | e30556e98896495d2d464ed8bb52af911ebd5377 | |
parent | 66c739040bba9a4b2ae4b66a86bde1b738e06fec (diff) | |
download | qtwebengine-chromium-b1ce3367b4895c1f57de79ef081f4b7bbaa011f8.tar.gz |
[Backport] CVE-2019-13660
Improve dropping fullscreen for security.
If dropping fullscreen for security, drop all pages in the
opener chain that are in fullscreen.
BUG=882363
TEST=as in bug
Change-Id: Ia730989dd77ff05fd724b1ead97dfa836e5b19e2
Commit-Queue: Avi Drissman <avi@chromium.org>
Reviewed-by: Robert Sesek <rsesek@chromium.org>
Cr-Commit-Position: refs/heads/master@{#671076}
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
-rw-r--r-- | chromium/content/browser/web_contents/web_contents_impl.cc | 21 | ||||
-rw-r--r-- | chromium/content/browser/web_contents/web_contents_impl_browsertest.cc | 34 |
2 files changed, 53 insertions, 2 deletions
diff --git a/chromium/content/browser/web_contents/web_contents_impl.cc b/chromium/content/browser/web_contents/web_contents_impl.cc index 27294d451fc..481c6ec2708 100644 --- a/chromium/content/browser/web_contents/web_contents_impl.cc +++ b/chromium/content/browser/web_contents/web_contents_impl.cc @@ -5970,11 +5970,28 @@ void WebContentsImpl::EnsureOpenerProxiesExist(RenderFrameHost* source_rfh) { } void WebContentsImpl::ForSecurityDropFullscreen() { - WebContentsImpl* web_contents = this; + // There are two chains of WebContents to kick out of fullscreen. + // + // Chain 1, the inner/outer WebContents chain. If an inner WebContents has + // done something that requires the browser to drop fullscreen, drop + // fullscreen from it and any outer WebContents that may be in fullscreen. + // + // Chain 2, the opener WebContents chain. If a WebContents has done something + // that requires the browser to drop fullscreen, drop fullscreen from any + // WebContents that was involved in the chain of opening it. + // + // Note that these two chains don't interact, as only a top-level WebContents + // can have an opener. This simplifies things. + + WebContents* web_contents = this; while (web_contents) { if (web_contents->IsFullscreenForCurrentTab()) web_contents->ExitFullscreen(true); - web_contents = web_contents->GetOuterWebContents(); + + if (web_contents->HasOriginalOpener()) + web_contents = FromRenderFrameHost(web_contents->GetOriginalOpener()); + else + web_contents = web_contents->GetOuterWebContents(); } } diff --git a/chromium/content/browser/web_contents/web_contents_impl_browsertest.cc b/chromium/content/browser/web_contents/web_contents_impl_browsertest.cc index 4f0ae7b69b7..dc3e43758e5 100644 --- a/chromium/content/browser/web_contents/web_contents_impl_browsertest.cc +++ b/chromium/content/browser/web_contents/web_contents_impl_browsertest.cc @@ -1769,6 +1769,8 @@ class TestWCDelegateForDialogsAndFullscreen : public JavaScriptDialogManager, std::string last_message() { return last_message_; } + WebContents* last_popup() { return popup_.get(); } + // WebContentsDelegate JavaScriptDialogManager* GetJavaScriptDialogManager( @@ -2462,6 +2464,38 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, EXPECT_FALSE(wc->IsFullscreenForCurrentTab()); } +// Tests that if a popup is opened, all WebContentses down the opener chain are +// kicked out of fullscreen. +IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, + PopupsOfPopupsFromJavaScriptEndFullscreen) { + WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell()->web_contents()); + TestWCDelegateForDialogsAndFullscreen test_delegate(wc); + + GURL url("about:blank"); + EXPECT_TRUE(NavigateToURL(shell(), url)); + + // Make a popup. + std::string popup_script = "window.open('', '', 'width=200,height=100')"; + test_delegate.WillWaitForNewContents(); + EXPECT_TRUE(content::ExecuteScript(wc, popup_script)); + test_delegate.Wait(); + WebContentsImpl* popup = + static_cast<WebContentsImpl*>(test_delegate.last_popup()); + + // Put the original page into fullscreen. + wc->EnterFullscreenMode(url, blink::WebFullscreenOptions()); + EXPECT_TRUE(wc->IsFullscreenForCurrentTab()); + + // Have the popup open a popup. + TestWCDelegateForDialogsAndFullscreen popup_test_delegate(popup); + popup_test_delegate.WillWaitForNewContents(); + EXPECT_TRUE(content::ExecuteScript(popup, popup_script)); + popup_test_delegate.Wait(); + + // Ensure the original page, being in the opener chain, loses fullscreen. + EXPECT_FALSE(wc->IsFullscreenForCurrentTab()); +} + IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, FocusFromJavaScriptEndsFullscreen) { WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell()->web_contents()); |