summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2019-10-14 14:23:40 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2019-10-16 09:04:55 +0000
commitb1ce3367b4895c1f57de79ef081f4b7bbaa011f8 (patch)
treee30556e98896495d2d464ed8bb52af911ebd5377
parent66c739040bba9a4b2ae4b66a86bde1b738e06fec (diff)
downloadqtwebengine-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.cc21
-rw-r--r--chromium/content/browser/web_contents/web_contents_impl_browsertest.cc34
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());