blob: 334f1013bcccf146c162d223fbfd0aed427a188e [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/test/scoped_feature_list.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/shell/browser/shell.h"
#include "net/dns/mock_host_resolver.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/mojom/cross_origin_opener_policy.mojom.h"
namespace content {
class CrossOriginOpenerPolicyBrowserTest : public ContentBrowserTest {
public:
CrossOriginOpenerPolicyBrowserTest() {
std::vector<base::Feature> features;
feature_list_.InitWithFeatures({network::features::kCrossOriginIsolation},
{});
}
protected:
void SetUpOnMainThread() override {
host_resolver()->AddRule("*", "127.0.0.1");
ASSERT_TRUE(embedded_test_server()->Start());
}
WebContentsImpl* web_contents() const {
return static_cast<WebContentsImpl*>(shell()->web_contents());
}
RenderFrameHostImpl* current_frame_host() {
return web_contents()->GetFrameTree()->root()->current_frame_host();
}
base::test::ScopedFeatureList feature_list_;
};
IN_PROC_BROWSER_TEST_F(CrossOriginOpenerPolicyBrowserTest,
NewPopupCOOP_InheritsSameOrigin) {
GURL starting_page(embedded_test_server()->GetURL(
"a.com", "/cross_site_iframe_factory.html?a(a)"));
EXPECT_TRUE(NavigateToURL(shell(), starting_page));
RenderFrameHostImpl* main_frame = current_frame_host();
main_frame->set_cross_origin_opener_policy(
network::mojom::CrossOriginOpenerPolicy::kSameOrigin);
ShellAddedObserver shell_observer;
RenderFrameHostImpl* iframe = main_frame->child_at(0)->current_frame_host();
EXPECT_TRUE(ExecJs(iframe, "window.open('about:blank')"));
RenderFrameHostImpl* popup_frame =
static_cast<WebContentsImpl*>(shell_observer.GetShell()->web_contents())
->GetFrameTree()
->root()
->current_frame_host();
EXPECT_EQ(main_frame->cross_origin_opener_policy(),
network::mojom::CrossOriginOpenerPolicy::kSameOrigin);
EXPECT_EQ(popup_frame->cross_origin_opener_policy(),
network::mojom::CrossOriginOpenerPolicy::kSameOrigin);
}
IN_PROC_BROWSER_TEST_F(CrossOriginOpenerPolicyBrowserTest,
NewPopupCOOP_InheritsSameOriginAllowPopups) {
GURL starting_page(embedded_test_server()->GetURL(
"a.com", "/cross_site_iframe_factory.html?a(a)"));
EXPECT_TRUE(NavigateToURL(shell(), starting_page));
RenderFrameHostImpl* main_frame = current_frame_host();
main_frame->set_cross_origin_opener_policy(
network::mojom::CrossOriginOpenerPolicy::kSameOriginAllowPopups);
ShellAddedObserver shell_observer;
RenderFrameHostImpl* iframe = main_frame->child_at(0)->current_frame_host();
EXPECT_TRUE(ExecJs(iframe, "window.open('about:blank')"));
RenderFrameHostImpl* popup_frame =
static_cast<WebContentsImpl*>(shell_observer.GetShell()->web_contents())
->GetFrameTree()
->root()
->current_frame_host();
EXPECT_EQ(main_frame->cross_origin_opener_policy(),
network::mojom::CrossOriginOpenerPolicy::kSameOriginAllowPopups);
EXPECT_EQ(popup_frame->cross_origin_opener_policy(),
network::mojom::CrossOriginOpenerPolicy::kSameOriginAllowPopups);
}
IN_PROC_BROWSER_TEST_F(CrossOriginOpenerPolicyBrowserTest,
NewPopupCOOP_CrossOriginDoesNotInherit) {
GURL starting_page(embedded_test_server()->GetURL(
"a.com", "/cross_site_iframe_factory.html?a(b)"));
EXPECT_TRUE(NavigateToURL(shell(), starting_page));
RenderFrameHostImpl* main_frame = current_frame_host();
main_frame->set_cross_origin_opener_policy(
network::mojom::CrossOriginOpenerPolicy::kSameOrigin);
ShellAddedObserver shell_observer;
RenderFrameHostImpl* iframe = main_frame->child_at(0)->current_frame_host();
EXPECT_TRUE(ExecJs(iframe, "window.open('about:blank')"));
RenderFrameHostImpl* popup_frame =
static_cast<WebContentsImpl*>(shell_observer.GetShell()->web_contents())
->GetFrameTree()
->root()
->current_frame_host();
EXPECT_EQ(main_frame->cross_origin_opener_policy(),
network::mojom::CrossOriginOpenerPolicy::kSameOrigin);
EXPECT_EQ(popup_frame->cross_origin_opener_policy(),
network::mojom::CrossOriginOpenerPolicy::kUnsafeNone);
}
IN_PROC_BROWSER_TEST_F(
CrossOriginOpenerPolicyBrowserTest,
NewPopupCOOP_SameOriginPolicyAndCrossOriginIframeSetsNoopener) {
GURL starting_page(embedded_test_server()->GetURL(
"a.com", "/cross_site_iframe_factory.html?a(b)"));
EXPECT_TRUE(NavigateToURL(shell(), starting_page));
RenderFrameHostImpl* main_frame = current_frame_host();
main_frame->set_cross_origin_opener_policy(
network::mojom::CrossOriginOpenerPolicy::kSameOrigin);
ShellAddedObserver new_shell_observer;
RenderFrameHostImpl* iframe = main_frame->child_at(0)->current_frame_host();
EXPECT_TRUE(ExecJs(iframe, "window.open('about:blank')"));
Shell* new_shell = new_shell_observer.GetShell();
RenderFrameHostImpl* popup_frame =
static_cast<WebContentsImpl*>(new_shell->web_contents())
->GetFrameTree()
->root()
->current_frame_host();
scoped_refptr<SiteInstance> main_frame_site_instance(
main_frame->GetSiteInstance());
scoped_refptr<SiteInstance> iframe_site_instance(iframe->GetSiteInstance());
scoped_refptr<SiteInstance> popup_site_instance(
popup_frame->GetSiteInstance());
ASSERT_TRUE(main_frame_site_instance);
ASSERT_TRUE(iframe_site_instance);
ASSERT_TRUE(popup_site_instance);
EXPECT_FALSE(main_frame_site_instance->IsRelatedSiteInstance(
popup_site_instance.get()));
EXPECT_FALSE(
iframe_site_instance->IsRelatedSiteInstance(popup_site_instance.get()));
// Check that `window.opener` is not set.
bool success = false;
EXPECT_TRUE(ExecuteScriptAndExtractBool(
new_shell, "window.domAutomationController.send(window.opener == null);",
&success));
EXPECT_TRUE(success) << "window.opener is set";
}
IN_PROC_BROWSER_TEST_F(CrossOriginOpenerPolicyBrowserTest,
NetworkErrorOnSandboxedPopups) {
GURL starting_page(embedded_test_server()->GetURL(
"a.com", "/cross-origin-opener-policy_sandbox_popup.html"));
EXPECT_TRUE(NavigateToURL(shell(), starting_page));
ShellAddedObserver shell_observer;
RenderFrameHostImpl* iframe =
current_frame_host()->child_at(0)->current_frame_host();
EXPECT_TRUE(ExecJs(
iframe, "window.open('/cross-origin-opener-policy_same-origin.html')"));
auto* popup_webcontents =
static_cast<WebContentsImpl*>(shell_observer.GetShell()->web_contents());
WaitForLoadStop(popup_webcontents);
EXPECT_EQ(
popup_webcontents->GetController().GetLastCommittedEntry()->GetPageType(),
PAGE_TYPE_ERROR);
}
IN_PROC_BROWSER_TEST_F(CrossOriginOpenerPolicyBrowserTest,
NoNetworkErrorOnSandboxedDocuments) {
GURL starting_page(embedded_test_server()->GetURL(
"a.com", "/cross-origin-opener-policy_csp_sandboxed.html"));
EXPECT_TRUE(NavigateToURL(shell(), starting_page));
EXPECT_NE(current_frame_host()->active_sandbox_flags(),
blink::mojom::WebSandboxFlags::kNone)
<< "Document should be sandboxed.";
GURL next_page(embedded_test_server()->GetURL(
"a.com", "/cross-origin-opener-policy_same-origin.html"));
EXPECT_TRUE(NavigateToURL(shell(), next_page));
EXPECT_EQ(
web_contents()->GetController().GetLastCommittedEntry()->GetPageType(),
PAGE_TYPE_NORMAL);
}
} // namespace content