#include "services/network/public/cpp/document_isolation_policy.h"
#include "base/command_line.h"
#include "base/strings/escape.h"
#include "base/strings/stringprintf.h"
#include "base/test/bind.h"
#include "base/test/gtest_util.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/with_feature_override.h"
#include "build/build_config.h"
#include "content/browser/process_lock.h"
#include "content/browser/renderer_host/navigation_request.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/content_navigation_policy.h"
#include "content/public/browser/site_isolation_policy.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/back_forward_cache_util.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_content_browser_client.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/content_mock_cert_verifier.h"
#include "content/public/test/prerender_test_util.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/url_loader_interceptor.h"
#include "content/shell/browser/shell.h"
#include "content/test/content_browser_test_utils_internal.h"
#include "content/test/render_document_feature.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/default_handlers.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
#include "net/test/embedded_test_server/request_handler_util.h"
#include "services/network/public/cpp/cross_origin_embedder_policy.h"
#include "services/network/public/cpp/features.h"
#include "testing/gmock/include/gmock/gmock.h"
using ::testing::HasSubstr;
namespace content {
namespace {
network::DocumentIsolationPolicy DipIsolateAndRequireCorp() {
network::DocumentIsolationPolicy dip;
dip.value =
network::mojom::DocumentIsolationPolicyValue::kIsolateAndRequireCorp;
return dip;
}
network::DocumentIsolationPolicy DipIsolateAndCredentialless() {
network::DocumentIsolationPolicy dip;
dip.value =
network::mojom::DocumentIsolationPolicyValue::kIsolateAndCredentialless;
return dip;
}
network::DocumentIsolationPolicy DipNone() {
return network::DocumentIsolationPolicy();
}
std::unique_ptr<net::test_server::HttpResponse> ServeDipOnSecondNavigation(
unsigned int& navigation_counter,
const net::test_server::HttpRequest& request) {
++navigation_counter;
auto http_response = std::make_unique<net::test_server::BasicHttpResponse>();
http_response->set_code(net::HttpStatusCode::HTTP_OK);
http_response->AddCustomHeader("Cache-Control", "no-store, must-revalidate");
if (navigation_counter > 1) {
http_response->AddCustomHeader("Document-Isolation-Policy",
"isolate-and-require-corp");
}
return http_response;
}
class DocumentIsolationPolicyBrowserTest
: public ContentBrowserTest,
public ::testing::WithParamInterface<
std::tuple<std::string, bool, bool>> {
public:
DocumentIsolationPolicyBrowserTest()
: prerender_helper_(base::BindRepeating(
&DocumentIsolationPolicyBrowserTest::prerender_web_contents,
base::Unretained(this))),
https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {
feature_list_.InitWithFeatures(
{network::features::kDocumentIsolationPolicy},
{features::kDeferSpeculativeRFHCreation, features::kSharedArrayBuffer});
InitAndEnableRenderDocumentFeature(&feature_list_for_render_document_,
std::get<0>(GetParam()));
if (IsBackForwardCacheEnabled()) {
feature_list_for_back_forward_cache_.InitWithFeaturesAndParameters(
GetDefaultEnabledBackForwardCacheFeaturesForTesting(
false),
GetDefaultDisabledBackForwardCacheFeaturesForTesting());
} else {
feature_list_for_back_forward_cache_.InitWithFeatures(
{}, {features::kBackForwardCache});
}
}
static std::string DescribeParams(
const testing::TestParamInfo<ParamType>& info) {
auto [render_document_level, enable_back_forward_cache, require_corp] =
info.param;
return base::StringPrintf(
"%s_%s_%s",
GetRenderDocumentLevelNameForTestParams(render_document_level).c_str(),
enable_back_forward_cache ? "BFCacheEnabled" : "BFCacheDisabled",
require_corp ? "RequireCorp" : "Credentialless");
}
bool IsBackForwardCacheEnabled() { return std::get<1>(GetParam()); }
net::EmbeddedTestServer* https_server() { return &https_server_; }
test::PrerenderTestHelper& prerender_helper() { return prerender_helper_; }
protected:
WebContentsImpl* web_contents() const {
return static_cast<WebContentsImpl*>(shell()->web_contents());
}
RenderFrameHostImpl* current_frame_host() {
return web_contents()->GetPrimaryMainFrame();
}
void SetUpOnMainThread() override {
ContentBrowserTest::SetUpOnMainThread();
mock_cert_verifier_.mock_cert_verifier()->set_default_result(net::OK);
host_resolver()->AddRule("*", "127.0.0.1");
ASSERT_TRUE(embedded_test_server()->Start());
https_server()->ServeFilesFromSourceDirectory(GetTestDataFilePath());
SetupCrossSiteRedirector(https_server());
net::test_server::RegisterDefaultHandlers(&https_server_);
AddRedirectOnSecondNavigationHandler(&https_server_);
unsigned int navigation_counter = 0;
https_server_.RegisterDefaultHandler(base::BindRepeating(
&net::test_server::HandlePrefixedRequest,
"/serve-dip-on-second-navigation",
base::BindRepeating(&ServeDipOnSecondNavigation,
base::OwnedRef(navigation_counter))));
prerender_helper().RegisterServerRequestMonitor(&https_server_);
ASSERT_TRUE(https_server()->Start());
}
GURL GetDocumentIsolationPolicyURL(
const std::string& host,
const std::optional<std::string>& additional_header = std::nullopt) {
std::string headers = "/set-header?";
if (std::get<2>(GetParam())) {
headers += "document-isolation-policy: isolate-and-require-corp";
} else {
headers += "document-isolation-policy: isolate-and-credentialless";
}
if (additional_header.has_value()) {
headers += "&" + additional_header.value();
}
return https_server()->GetURL(host, headers);
}
network::DocumentIsolationPolicy GetDocumentIsolationPolicy() {
if (std::get<2>(GetParam())) {
return DipIsolateAndRequireCorp();
}
return DipIsolateAndCredentialless();
}
private:
void SetUpCommandLine(base::CommandLine* command_line) override {
mock_cert_verifier_.SetUpCommandLine(command_line);
IsolateAllSitesForTesting(command_line);
}
void SetUpInProcessBrowserTestFixture() override {
ContentBrowserTest::SetUpInProcessBrowserTestFixture();
mock_cert_verifier_.SetUpInProcessBrowserTestFixture();
}
void TearDownInProcessBrowserTestFixture() override {
ContentBrowserTest::TearDownInProcessBrowserTestFixture();
mock_cert_verifier_.TearDownInProcessBrowserTestFixture();
}
WebContents* prerender_web_contents() { return shell()->web_contents(); }
content::ContentMockCertVerifier mock_cert_verifier_;
test::PrerenderTestHelper prerender_helper_;
base::test::ScopedFeatureList feature_list_;
base::test::ScopedFeatureList feature_list_for_render_document_;
base::test::ScopedFeatureList feature_list_for_back_forward_cache_;
net::EmbeddedTestServer https_server_;
};
class DocumentIsolationPolicyWithoutFeatureBrowserTest
: public ContentBrowserTest,
public ::testing::WithParamInterface<
std::tuple<std::string, bool, bool>> {
public:
DocumentIsolationPolicyWithoutFeatureBrowserTest()
: https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {
feature_list_.InitWithFeatures(
{}, {network::features::kDocumentIsolationPolicy});
InitAndEnableRenderDocumentFeature(&feature_list_for_render_document_,
std::get<0>(GetParam()));
if (IsBackForwardCacheEnabled()) {
feature_list_for_back_forward_cache_.InitWithFeaturesAndParameters(
GetDefaultEnabledBackForwardCacheFeaturesForTesting(
false),
GetDefaultDisabledBackForwardCacheFeaturesForTesting());
} else {
feature_list_for_back_forward_cache_.InitWithFeatures(
{}, {features::kBackForwardCache});
}
}
static std::string DescribeParams(
const testing::TestParamInfo<ParamType>& info) {
auto [render_document_level, enable_back_forward_cache, require_corp] =
info.param;
return base::StringPrintf(
"%s_%s_%s",
GetRenderDocumentLevelNameForTestParams(render_document_level).c_str(),
enable_back_forward_cache ? "BFCacheEnabled" : "BFCacheDisabled",
require_corp ? "RequireCorp" : "Credentialless");
}
net::EmbeddedTestServer* https_server() { return &https_server_; }
protected:
RenderFrameHostImpl* current_frame_host() {
return static_cast<WebContentsImpl*>(shell()->web_contents())
->GetPrimaryMainFrame();
}
GURL GetDocumentIsolationPolicyURL(const std::string& host) {
if (std::get<2>(GetParam())) {
return https_server()->GetURL(
host,
"/set-header?document-isolation-policy: isolate-and-require-corp");
}
return https_server()->GetURL(
host,
"/set-header?document-isolation-policy: isolate-and-credentialless");
}
void SetUpOnMainThread() override {
ContentBrowserTest::SetUpOnMainThread();
mock_cert_verifier_.mock_cert_verifier()->set_default_result(net::OK);
host_resolver()->AddRule("*", "127.0.0.1");
ASSERT_TRUE(embedded_test_server()->Start());
https_server()->ServeFilesFromSourceDirectory(GetTestDataFilePath());
SetupCrossSiteRedirector(https_server());
net::test_server::RegisterDefaultHandlers(&https_server_);
ASSERT_TRUE(https_server()->Start());
}
private:
void SetUpCommandLine(base::CommandLine* command_line) override {
ContentBrowserTest::SetUpCommandLine(command_line);
mock_cert_verifier_.SetUpCommandLine(command_line);
}
void SetUpInProcessBrowserTestFixture() override {
ContentBrowserTest::SetUpInProcessBrowserTestFixture();
mock_cert_verifier_.SetUpInProcessBrowserTestFixture();
}
void TearDownInProcessBrowserTestFixture() override {
ContentBrowserTest::TearDownInProcessBrowserTestFixture();
mock_cert_verifier_.TearDownInProcessBrowserTestFixture();
}
content::ContentMockCertVerifier mock_cert_verifier_;
base::test::ScopedFeatureList feature_list_;
base::test::ScopedFeatureList feature_list_for_render_document_;
base::test::ScopedFeatureList feature_list_for_back_forward_cache_;
net::EmbeddedTestServer https_server_;
};
class DocumentIsolationPolicyWithoutSiteIsolationBrowserTest
: public DocumentIsolationPolicyBrowserTest {
public:
DocumentIsolationPolicyWithoutSiteIsolationBrowserTest() = default;
private:
void SetUpCommandLine(base::CommandLine* command_line) override {
ContentBrowserTest::SetUpCommandLine(command_line);
mock_cert_verifier_.SetUpCommandLine(command_line);
command_line->AppendSwitch(switches::kDisableSiteIsolation);
}
content::ContentMockCertVerifier mock_cert_verifier_;
};
}
IN_PROC_BROWSER_TEST_P(DocumentIsolationPolicyWithoutFeatureBrowserTest,
DIP_Disabled) {
GURL starting_page = GetDocumentIsolationPolicyURL("a.test");
EXPECT_TRUE(NavigateToURL(shell(), starting_page));
EXPECT_EQ(current_frame_host()
->policy_container_host()
->policies()
.document_isolation_policy,
DipNone());
}
IN_PROC_BROWSER_TEST_P(DocumentIsolationPolicyWithoutSiteIsolationBrowserTest,
DIP_Disabled) {
GURL starting_page = GetDocumentIsolationPolicyURL("a.test");
EXPECT_TRUE(NavigateToURL(shell(), starting_page));
EXPECT_EQ(current_frame_host()
->policy_container_host()
->policies()
.document_isolation_policy,
DipNone());
}
IN_PROC_BROWSER_TEST_P(DocumentIsolationPolicyBrowserTest,
NewPopup_InheritsDIP) {
GURL starting_page = GetDocumentIsolationPolicyURL("a.test");
GURL no_dip(https_server()->GetURL("a.test", "/empty.html"));
EXPECT_TRUE(NavigateToURL(shell(), starting_page));
RenderFrameHostImpl* main_rfh = current_frame_host();
ShellAddedObserver shell_observer;
EXPECT_TRUE(ExecJs(main_rfh, "window.open('about:blank')"));
auto* popup_webcontents =
static_cast<WebContentsImpl*>(shell_observer.GetShell()->web_contents());
RenderFrameHostImpl* popup_rfh = popup_webcontents->GetPrimaryMainFrame();
EXPECT_EQ(
main_rfh->policy_container_host()->policies().document_isolation_policy,
GetDocumentIsolationPolicy());
EXPECT_EQ(
popup_rfh->policy_container_host()->policies().document_isolation_policy,
GetDocumentIsolationPolicy());
ASSERT_TRUE(NavigateToURL(popup_webcontents, no_dip));
popup_rfh = popup_webcontents->GetPrimaryMainFrame();
EXPECT_EQ(
popup_rfh->policy_container_host()->policies().document_isolation_policy,
DipNone());
ASSERT_TRUE(ExecJs(main_rfh, R"(
const frame = document.createElement('iframe');
frame.src = '/empty.html';
document.body.appendChild(frame);
)"));
EXPECT_TRUE(WaitForLoadStop(web_contents()));
ShellAddedObserver shell_observer_2;
RenderFrameHostImpl* iframe_rfh = main_rfh->child_at(0)->current_frame_host();
EXPECT_TRUE(ExecJs(iframe_rfh, "window.open('about:blank')"));
RenderFrameHostImpl* popup_rfh_2 =
static_cast<WebContentsImpl*>(shell_observer_2.GetShell()->web_contents())
->GetPrimaryMainFrame();
EXPECT_EQ(
iframe_rfh->policy_container_host()->policies().document_isolation_policy,
DipNone());
EXPECT_EQ(popup_rfh_2->policy_container_host()
->policies()
.document_isolation_policy,
DipNone());
}
IN_PROC_BROWSER_TEST_P(DocumentIsolationPolicyBrowserTest, BlobInheritsDIP) {
GURL starting_page = GetDocumentIsolationPolicyURL("a.test");
EXPECT_TRUE(NavigateToURL(shell(), starting_page));
ShellAddedObserver shell_observer;
ASSERT_TRUE(ExecJs(current_frame_host(), R"(
const blob = new Blob(['foo'], {type : 'text/html'});
const url = URL.createObjectURL(blob);
window.open(url);
)"));
EXPECT_TRUE(WaitForLoadStop(shell_observer.GetShell()->web_contents()));
RenderFrameHostImpl* popup_rfh =
static_cast<WebContentsImpl*>(shell_observer.GetShell()->web_contents())
->GetPrimaryMainFrame();
EXPECT_EQ(
popup_rfh->policy_container_host()->policies().document_isolation_policy,
GetDocumentIsolationPolicy());
}
IN_PROC_BROWSER_TEST_P(DocumentIsolationPolicyBrowserTest,
AboutBlankInheritsDip) {
GURL starting_page = GetDocumentIsolationPolicyURL("a.test");
EXPECT_TRUE(NavigateToURL(shell(), starting_page));
EXPECT_EQ(current_frame_host()
->policy_container_host()
->policies()
.document_isolation_policy,
GetDocumentIsolationPolicy());
EXPECT_TRUE(ExecJs(current_frame_host(),
"g_iframe = document.createElement('iframe');"
"g_iframe.src = 'about:blank';"
"document.body.appendChild(g_iframe);"));
WaitForLoadStop(web_contents());
RenderFrameHostImpl* iframe_rfh =
current_frame_host()->child_at(0)->current_frame_host();
EXPECT_EQ(
iframe_rfh->policy_container_host()->policies().document_isolation_policy,
GetDocumentIsolationPolicy());
}
IN_PROC_BROWSER_TEST_P(DocumentIsolationPolicyBrowserTest, IframeCanSetDip) {
GURL starting_page(
https_server()->GetURL("a.com", "/cross_site_iframe_factory.html?a(b)"));
GURL iframe_navigation_url = GetDocumentIsolationPolicyURL("b.com");
EXPECT_TRUE(NavigateToURL(shell(), starting_page));
RenderFrameHostImpl* main_rfh = current_frame_host();
FrameTreeNode* iframe_ftn = main_rfh->child_at(0);
RenderFrameHostImpl* iframe_rfh = iframe_ftn->current_frame_host();
scoped_refptr<SiteInstanceImpl> non_dip_iframe_site_instance =
iframe_rfh->GetSiteInstance();
EXPECT_EQ(
iframe_rfh->policy_container_host()->policies().document_isolation_policy,
DipNone());
EXPECT_TRUE(NavigateToURLFromRenderer(iframe_ftn, iframe_navigation_url));
iframe_rfh = iframe_ftn->current_frame_host();
EXPECT_EQ(iframe_rfh->GetLastCommittedURL(), iframe_navigation_url);
EXPECT_NE(iframe_rfh->GetSiteInstance(), non_dip_iframe_site_instance);
EXPECT_EQ(
iframe_rfh->policy_container_host()->policies().document_isolation_policy,
GetDocumentIsolationPolicy());
}
IN_PROC_BROWSER_TEST_P(DocumentIsolationPolicyBrowserTest,
NonDipPageCrashIntoDip) {
GURL non_dip_page(https_server()->GetURL("a.test", "/title1.html"));
GURL dip_page = GetDocumentIsolationPolicyURL("a.test");
{
EXPECT_TRUE(NavigateToURL(shell(), non_dip_page));
scoped_refptr<SiteInstance> initial_site_instance(
current_frame_host()->GetSiteInstance());
RenderProcessHost* process = initial_site_instance->GetProcess();
ASSERT_TRUE(process);
std::unique_ptr<RenderProcessHostWatcher> crash_observer(
new RenderProcessHostWatcher(
process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT));
process->Shutdown(0);
crash_observer->Wait();
crash_observer.reset();
EXPECT_TRUE(NavigateToURL(shell(), dip_page));
EXPECT_EQ(current_frame_host()
->policy_container_host()
->policies()
.document_isolation_policy,
GetDocumentIsolationPolicy());
}
{
EXPECT_TRUE(NavigateToURL(shell(), non_dip_page));
scoped_refptr<SiteInstance> initial_site_instance(
current_frame_host()->GetSiteInstance());
TestNavigationManager dip_navigation(web_contents(), dip_page);
shell()->LoadURL(dip_page);
EXPECT_TRUE(dip_navigation.WaitForRequestStart());
RenderProcessHost* process = initial_site_instance->GetProcess();
ASSERT_TRUE(process);
std::unique_ptr<RenderProcessHostWatcher> crash_observer(
new RenderProcessHostWatcher(
process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT));
process->Shutdown(0);
crash_observer->Wait();
crash_observer.reset();
ASSERT_TRUE(dip_navigation.WaitForNavigationFinished());
if (!base::FeatureList::IsEnabled(
features::kResumeNavigationWithSpeculativeRFHProcessGone) &&
(ShouldCreateNewHostForAllFrames() || IsBackForwardCacheEnabled())) {
EXPECT_FALSE(dip_navigation.was_committed());
return;
}
EXPECT_TRUE(dip_navigation.was_successful());
EXPECT_EQ(current_frame_host()
->policy_container_host()
->policies()
.document_isolation_policy,
GetDocumentIsolationPolicy());
}
}
IN_PROC_BROWSER_TEST_P(DocumentIsolationPolicyBrowserTest,
DipPageCrashIntoNonDip) {
GURL dip_page = GetDocumentIsolationPolicyURL("a.test");
GURL non_dip_page(https_server()->GetURL("a.test", "/empty.html"));
{
EXPECT_TRUE(NavigateToURL(shell(), dip_page));
scoped_refptr<SiteInstance> initial_site_instance(
current_frame_host()->GetSiteInstance());
RenderProcessHost* process = initial_site_instance->GetProcess();
ASSERT_TRUE(process);
std::unique_ptr<RenderProcessHostWatcher> crash_observer(
new RenderProcessHostWatcher(
process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT));
process->Shutdown(0);
crash_observer->Wait();
crash_observer.reset();
EXPECT_TRUE(NavigateToURL(shell(), non_dip_page));
EXPECT_EQ(current_frame_host()
->policy_container_host()
->policies()
.document_isolation_policy,
DipNone());
}
{
EXPECT_TRUE(NavigateToURL(shell(), dip_page));
scoped_refptr<SiteInstance> initial_site_instance(
current_frame_host()->GetSiteInstance());
TestNavigationManager non_dip_navigation(web_contents(), non_dip_page);
shell()->LoadURL(non_dip_page);
EXPECT_TRUE(non_dip_navigation.WaitForRequestStart());
RenderProcessHost* process = initial_site_instance->GetProcess();
ASSERT_TRUE(process);
std::unique_ptr<RenderProcessHostWatcher> crash_observer(
new RenderProcessHostWatcher(
process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT));
process->Shutdown(0);
crash_observer->Wait();
crash_observer.reset();
ASSERT_TRUE(non_dip_navigation.WaitForNavigationFinished());
if (!base::FeatureList::IsEnabled(
features::kResumeNavigationWithSpeculativeRFHProcessGone) &&
(ShouldCreateNewHostForAllFrames() || IsBackForwardCacheEnabled())) {
EXPECT_FALSE(non_dip_navigation.was_committed());
EXPECT_EQ(current_frame_host()
->policy_container_host()
->policies()
.document_isolation_policy,
GetDocumentIsolationPolicy());
return;
}
EXPECT_TRUE(non_dip_navigation.was_successful());
EXPECT_EQ(current_frame_host()
->policy_container_host()
->policies()
.document_isolation_policy,
DipNone());
}
{
EXPECT_TRUE(NavigateToURL(shell(), dip_page));
scoped_refptr<SiteInstance> initial_site_instance(
current_frame_host()->GetSiteInstance());
TestNavigationManager non_dip_navigation(web_contents(), non_dip_page);
shell()->LoadURL(non_dip_page);
EXPECT_TRUE(non_dip_navigation.WaitForResponse());
RenderProcessHost* process = initial_site_instance->GetProcess();
ASSERT_TRUE(process);
std::unique_ptr<RenderProcessHostWatcher> crash_observer(
new RenderProcessHostWatcher(
process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT));
process->Shutdown(0);
crash_observer->Wait();
crash_observer.reset();
ASSERT_TRUE(non_dip_navigation.WaitForNavigationFinished());
EXPECT_TRUE(non_dip_navigation.was_successful());
EXPECT_EQ(current_frame_host()
->policy_container_host()
->policies()
.document_isolation_policy,
DipNone());
}
}
IN_PROC_BROWSER_TEST_P(DocumentIsolationPolicyBrowserTest,
DipPageCrashIntoDip) {
GURL dip_page = GetDocumentIsolationPolicyURL("a.test");
{
EXPECT_TRUE(NavigateToURL(shell(), dip_page));
scoped_refptr<SiteInstance> initial_site_instance(
current_frame_host()->GetSiteInstance());
EXPECT_EQ(current_frame_host()
->policy_container_host()
->policies()
.document_isolation_policy,
GetDocumentIsolationPolicy());
RenderProcessHost* process = initial_site_instance->GetProcess();
ASSERT_TRUE(process);
std::unique_ptr<RenderProcessHostWatcher> crash_observer(
new RenderProcessHostWatcher(
process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT));
process->Shutdown(0);
crash_observer->Wait();
crash_observer.reset();
ReloadBlockUntilNavigationsComplete(shell(), 1);
EXPECT_TRUE(current_frame_host()->GetSiteInstance()->IsRelatedSiteInstance(
initial_site_instance.get()));
EXPECT_EQ(current_frame_host()
->policy_container_host()
->policies()
.document_isolation_policy,
GetDocumentIsolationPolicy());
}
{
EXPECT_TRUE(NavigateToURL(shell(), dip_page));
scoped_refptr<SiteInstance> initial_site_instance(
current_frame_host()->GetSiteInstance());
TestNavigationManager dip_navigation(web_contents(), dip_page);
shell()->LoadURL(dip_page);
EXPECT_TRUE(dip_navigation.WaitForRequestStart());
RenderProcessHost* process = initial_site_instance->GetProcess();
ASSERT_TRUE(process);
std::unique_ptr<RenderProcessHostWatcher> crash_observer(
new RenderProcessHostWatcher(
process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT));
process->Shutdown(0);
crash_observer->Wait();
crash_observer.reset();
ASSERT_TRUE(dip_navigation.WaitForNavigationFinished());
EXPECT_EQ(current_frame_host()
->policy_container_host()
->policies()
.document_isolation_policy,
GetDocumentIsolationPolicy());
}
}
IN_PROC_BROWSER_TEST_P(DocumentIsolationPolicyBrowserTest,
IsolateInNewProcessDespiteLimitReached) {
RenderProcessHostImpl::SetMaxRendererProcessCount(1);
GURL starting_page(https_server()->GetURL("a.test", "/title1.html"));
EXPECT_TRUE(NavigateToURL(shell(), starting_page));
scoped_refptr<SiteInstance> initial_site_instance(
current_frame_host()->GetSiteInstance());
GURL url_openee = GetDocumentIsolationPolicyURL("a.test");
auto* popup_webcontents =
OpenPopup(current_frame_host(), url_openee, "popup")->web_contents();
EXPECT_TRUE(WaitForLoadStop(popup_webcontents));
EXPECT_NE(initial_site_instance,
popup_webcontents->GetPrimaryMainFrame()->GetSiteInstance());
EXPECT_NE(current_frame_host()->GetProcess(),
popup_webcontents->GetPrimaryMainFrame()->GetProcess());
}
IN_PROC_BROWSER_TEST_P(DocumentIsolationPolicyBrowserTest,
NoProcessReuseForDIPProcesses) {
RenderProcessHostImpl::SetMaxRendererProcessCount(1);
GURL starting_page = GetDocumentIsolationPolicyURL("a.test");
EXPECT_TRUE(NavigateToURL(shell(), starting_page));
scoped_refptr<SiteInstance> initial_site_instance(
current_frame_host()->GetSiteInstance());
Shell* new_shell = CreateBrowser();
GURL non_dip_url = https_server()->GetURL("a.test", "/title1.html");
EXPECT_TRUE(NavigateToURL(new_shell, non_dip_url));
EXPECT_NE(
initial_site_instance,
new_shell->web_contents()->GetPrimaryMainFrame()->GetSiteInstance());
EXPECT_NE(current_frame_host()->GetProcess(),
new_shell->web_contents()->GetPrimaryMainFrame()->GetProcess());
}
IN_PROC_BROWSER_TEST_P(DocumentIsolationPolicyBrowserTest,
SpeculativeRfhsAndDip) {
GURL non_dip_page(https_server()->GetURL("a.test", "/title1.html"));
GURL dip_page = GetDocumentIsolationPolicyURL("a.test");
{
SCOPED_TRACE("Non-DIP to DIP");
EXPECT_TRUE(NavigateToURL(shell(), non_dip_page));
scoped_refptr<SiteInstance> initial_site_instance(
current_frame_host()->GetSiteInstance());
TestNavigationManager dip_navigation(web_contents(), dip_page);
shell()->LoadURL(dip_page);
EXPECT_TRUE(dip_navigation.WaitForRequestStart());
auto* speculative_rfh = web_contents()
->GetPrimaryFrameTree()
.root()
->render_manager()
->speculative_frame_host();
if (CanSameSiteMainFrameNavigationsChangeRenderFrameHosts()) {
EXPECT_TRUE(speculative_rfh);
} else {
EXPECT_FALSE(speculative_rfh);
}
ASSERT_TRUE(dip_navigation.WaitForNavigationFinished());
EXPECT_FALSE(current_frame_host()->GetSiteInstance()->IsRelatedSiteInstance(
initial_site_instance.get()));
EXPECT_EQ(current_frame_host()
->policy_container_host()
->policies()
.document_isolation_policy,
GetDocumentIsolationPolicy());
}
{
SCOPED_TRACE("DIP to non-DIP");
EXPECT_TRUE(NavigateToURL(shell(), dip_page));
scoped_refptr<SiteInstance> initial_site_instance(
current_frame_host()->GetSiteInstance());
TestNavigationManager non_dip_navigation(web_contents(), non_dip_page);
shell()->LoadURL(non_dip_page);
EXPECT_TRUE(non_dip_navigation.WaitForRequestStart());
auto* speculative_rfh = web_contents()
->GetPrimaryFrameTree()
.root()
->render_manager()
->speculative_frame_host();
if (CanSameSiteMainFrameNavigationsChangeRenderFrameHosts()) {
EXPECT_TRUE(speculative_rfh);
} else {
EXPECT_FALSE(speculative_rfh);
}
ASSERT_TRUE(non_dip_navigation.WaitForNavigationFinished());
EXPECT_FALSE(current_frame_host()->GetSiteInstance()->IsRelatedSiteInstance(
initial_site_instance.get()));
EXPECT_EQ(current_frame_host()
->policy_container_host()
->policies()
.document_isolation_policy,
DipNone());
}
{
SCOPED_TRACE("DIP to DIP");
EXPECT_TRUE(NavigateToURL(shell(), dip_page));
scoped_refptr<SiteInstance> initial_site_instance(
current_frame_host()->GetSiteInstance());
TestNavigationManager dip_navigation(web_contents(), dip_page);
shell()->LoadURL(dip_page);
EXPECT_TRUE(dip_navigation.WaitForRequestStart());
auto* speculative_rfh = web_contents()
->GetPrimaryFrameTree()
.root()
->render_manager()
->speculative_frame_host();
if (WillSameSiteNavigationChangeRenderFrameHosts(true, true)) {
EXPECT_TRUE(speculative_rfh);
} else {
EXPECT_FALSE(speculative_rfh);
}
ASSERT_TRUE(dip_navigation.WaitForNavigationFinished());
EXPECT_TRUE(current_frame_host()->GetSiteInstance()->IsRelatedSiteInstance(
initial_site_instance.get()));
EXPECT_EQ(current_frame_host()
->policy_container_host()
->policies()
.document_isolation_policy,
GetDocumentIsolationPolicy());
}
}
IN_PROC_BROWSER_TEST_P(DocumentIsolationPolicyBrowserTest, DipOriginKeyed) {
GURL isolated_page = GetDocumentIsolationPolicyURL("a.test");
EXPECT_TRUE(NavigateToURL(shell(), isolated_page));
SiteInstanceImpl* current_si = current_frame_host()->GetSiteInstance();
EXPECT_TRUE(current_si->IsCrossOriginIsolated());
EXPECT_TRUE(current_si->GetSiteInfo().agent_cluster_key().IsOriginKeyed());
if (SiteIsolationPolicy::AreOriginKeyedProcessesEnabledByDefault()) {
EXPECT_EQ(AgentClusterKey::OACStatus::kOriginKeyedByDefault,
current_si->GetSiteInfo().oac_status());
} else {
EXPECT_EQ(AgentClusterKey::OACStatus::kSiteKeyedByDefault,
current_si->GetSiteInfo().oac_status());
}
}
IN_PROC_BROWSER_TEST_P(DocumentIsolationPolicyBrowserTest,
DipAgentClusterKeyUsesOrigin) {
GURL isolated_page = GetDocumentIsolationPolicyURL("a.b.test");
url::Origin origin = url::Origin::Create(isolated_page);
EXPECT_TRUE(NavigateToURL(shell(), isolated_page));
SiteInstanceImpl* current_si = current_frame_host()->GetSiteInstance();
EXPECT_TRUE(current_si->IsCrossOriginIsolated());
EXPECT_TRUE(current_si->GetSiteInfo().agent_cluster_key().IsOriginKeyed());
EXPECT_EQ(origin, current_si->GetSiteInfo().agent_cluster_key().GetOrigin());
}
IN_PROC_BROWSER_TEST_P(DocumentIsolationPolicyBrowserTest,
CrossOriginIsolatedSiteInstance_MainFrame) {
GURL isolated_page = GetDocumentIsolationPolicyURL("a.test");
GURL isolated_page_b = GetDocumentIsolationPolicyURL("cdn.a.test");
GURL non_isolated_page(https_server()->GetURL("a.test", "/title1.html"));
{
EXPECT_TRUE(NavigateToURL(shell(), non_isolated_page));
SiteInstanceImpl* current_si = current_frame_host()->GetSiteInstance();
EXPECT_FALSE(current_si->IsCrossOriginIsolated());
}
{
scoped_refptr<SiteInstanceImpl> previous_si =
current_frame_host()->GetSiteInstance();
EXPECT_TRUE(NavigateToURL(shell(), isolated_page));
SiteInstanceImpl* current_si = current_frame_host()->GetSiteInstance();
EXPECT_TRUE(current_si->IsCrossOriginIsolated());
EXPECT_NE(current_si->GetProcess(),
previous_si->GetOrCreateProcessForTesting());
EXPECT_FALSE(current_si->IsRelatedSiteInstance(previous_si.get()));
}
{
scoped_refptr<SiteInstanceImpl> previous_si =
current_frame_host()->GetSiteInstance();
EXPECT_TRUE(NavigateToURL(shell(), non_isolated_page));
SiteInstanceImpl* current_si = current_frame_host()->GetSiteInstance();
EXPECT_FALSE(current_si->IsCrossOriginIsolated());
EXPECT_NE(current_si->GetProcess(),
previous_si->GetOrCreateProcessForTesting());
EXPECT_FALSE(current_si->IsRelatedSiteInstance(previous_si.get()));
}
{
scoped_refptr<SiteInstanceImpl> previous_si =
current_frame_host()->GetSiteInstance();
web_contents()->GetController().GoBack();
EXPECT_TRUE(WaitForLoadStop(web_contents()));
SiteInstanceImpl* current_si = current_frame_host()->GetSiteInstance();
EXPECT_TRUE(current_si->IsCrossOriginIsolated());
EXPECT_NE(current_si->GetProcess(),
previous_si->GetOrCreateProcessForTesting());
EXPECT_FALSE(current_si->IsRelatedSiteInstance(previous_si.get()));
}
{
scoped_refptr<SiteInstanceImpl> previous_si =
current_frame_host()->GetSiteInstance();
web_contents()->GetController().GoBack();
EXPECT_TRUE(WaitForLoadStop(web_contents()));
SiteInstanceImpl* current_si = current_frame_host()->GetSiteInstance();
EXPECT_FALSE(current_si->IsCrossOriginIsolated());
EXPECT_NE(current_si->GetProcess(),
previous_si->GetOrCreateProcessForTesting());
EXPECT_FALSE(current_si->IsRelatedSiteInstance(previous_si.get()));
}
{
EXPECT_TRUE(NavigateToURL(shell(), isolated_page));
scoped_refptr<SiteInstanceImpl> site_instance_1 =
current_frame_host()->GetSiteInstance();
EXPECT_TRUE(NavigateToURL(shell(), isolated_page_b));
SiteInstanceImpl* site_instance_2 = current_frame_host()->GetSiteInstance();
EXPECT_TRUE(site_instance_1->IsCrossOriginIsolated());
EXPECT_TRUE(site_instance_2->IsCrossOriginIsolated());
EXPECT_NE(site_instance_1->GetOrCreateProcessForTesting(),
site_instance_2->GetProcess());
EXPECT_FALSE(site_instance_1->IsRelatedSiteInstance(site_instance_2));
}
}
IN_PROC_BROWSER_TEST_P(
DocumentIsolationPolicyBrowserTest,
CrossOriginIsolatedSiteInstance_MainFrameRendererInitiated) {
GURL isolated_page = GetDocumentIsolationPolicyURL("a.test");
GURL isolated_page_b = GetDocumentIsolationPolicyURL("cdn.a.test");
GURL non_isolated_page(https_server()->GetURL("a.test", "/title1.html"));
{
EXPECT_TRUE(NavigateToURL(shell(), non_isolated_page));
SiteInstanceImpl* current_si = current_frame_host()->GetSiteInstance();
EXPECT_FALSE(current_si->IsCrossOriginIsolated());
}
{
scoped_refptr<SiteInstanceImpl> previous_si =
current_frame_host()->GetSiteInstance();
EXPECT_TRUE(NavigateToURLFromRenderer(shell(), isolated_page));
SiteInstanceImpl* current_si = current_frame_host()->GetSiteInstance();
EXPECT_TRUE(current_si->IsCrossOriginIsolated());
EXPECT_NE(current_si->GetProcess(),
previous_si->GetOrCreateProcessForTesting());
if (IsBackForwardCacheEnabled()) {
EXPECT_FALSE(current_si->IsRelatedSiteInstance(previous_si.get()));
} else {
EXPECT_TRUE(current_si->IsRelatedSiteInstance(previous_si.get()));
}
}
{
scoped_refptr<SiteInstanceImpl> previous_si =
current_frame_host()->GetSiteInstance();
EXPECT_TRUE(NavigateToURLFromRenderer(shell(), isolated_page));
SiteInstanceImpl* current_si = current_frame_host()->GetSiteInstance();
EXPECT_TRUE(current_si->IsCrossOriginIsolated());
EXPECT_EQ(current_si, previous_si);
}
{
scoped_refptr<SiteInstanceImpl> previous_si =
current_frame_host()->GetSiteInstance();
EXPECT_TRUE(NavigateToURLFromRenderer(shell(), non_isolated_page));
SiteInstanceImpl* current_si = current_frame_host()->GetSiteInstance();
EXPECT_FALSE(current_si->IsCrossOriginIsolated());
EXPECT_NE(current_si->GetProcess(),
previous_si->GetOrCreateProcessForTesting());
if (IsBackForwardCacheEnabled()) {
EXPECT_FALSE(current_si->IsRelatedSiteInstance(previous_si.get()));
} else {
EXPECT_TRUE(current_si->IsRelatedSiteInstance(previous_si.get()));
}
}
{
scoped_refptr<SiteInstanceImpl> previous_si =
current_frame_host()->GetSiteInstance();
web_contents()->GetController().GoBack();
ASSERT_TRUE(WaitForLoadStop(web_contents()));
SiteInstanceImpl* current_si = current_frame_host()->GetSiteInstance();
EXPECT_TRUE(current_si->IsCrossOriginIsolated());
EXPECT_NE(current_si->GetProcess(),
previous_si->GetOrCreateProcessForTesting());
if (IsBackForwardCacheEnabled()) {
EXPECT_FALSE(current_si->IsRelatedSiteInstance(previous_si.get()));
} else {
EXPECT_TRUE(current_si->IsRelatedSiteInstance(previous_si.get()));
}
}
{
EXPECT_TRUE(NavigateToURLFromRenderer(shell(), isolated_page));
scoped_refptr<SiteInstanceImpl> site_instance_1 =
current_frame_host()->GetSiteInstance();
EXPECT_TRUE(NavigateToURLFromRenderer(shell(), isolated_page_b));
SiteInstanceImpl* site_instance_2 = current_frame_host()->GetSiteInstance();
EXPECT_TRUE(site_instance_1->IsCrossOriginIsolated());
EXPECT_TRUE(site_instance_2->IsCrossOriginIsolated());
EXPECT_NE(site_instance_1->GetOrCreateProcessForTesting(),
site_instance_2->GetProcess());
if (IsBackForwardCacheEnabled()) {
EXPECT_FALSE(
site_instance_2->IsRelatedSiteInstance(site_instance_1.get()));
} else {
EXPECT_TRUE(
site_instance_2->IsRelatedSiteInstance(site_instance_1.get()));
}
}
}
IN_PROC_BROWSER_TEST_P(DocumentIsolationPolicyBrowserTest,
CrossOriginIsolatedSiteInstance_IFrame) {
GURL isolated_page = GetDocumentIsolationPolicyURL("a.test");
GURL isolated_page_b = GetDocumentIsolationPolicyURL("cdn.a.test");
GURL non_isolated_page(https_server()->GetURL("a.test", "/title1.html"));
EXPECT_TRUE(NavigateToURL(shell(), isolated_page));
SiteInstanceImpl* main_si = current_frame_host()->GetSiteInstance();
EXPECT_TRUE(main_si->IsCrossOriginIsolated());
TestNavigationManager coi_iframe_navigation(web_contents(), isolated_page);
EXPECT_TRUE(
ExecJs(web_contents(),
JsReplace("const iframe = document.createElement('iframe'); "
"iframe.src = $1; "
"document.body.appendChild(iframe);",
isolated_page)));
ASSERT_TRUE(coi_iframe_navigation.WaitForNavigationFinished());
EXPECT_TRUE(coi_iframe_navigation.was_successful());
RenderFrameHostImpl* coi_iframe_rfh =
current_frame_host()->child_at(0)->current_frame_host();
SiteInstanceImpl* coi_iframe_si = coi_iframe_rfh->GetSiteInstance();
EXPECT_EQ(coi_iframe_si, main_si);
TestNavigationManager non_coi_iframe_navigation(web_contents(),
non_isolated_page);
EXPECT_TRUE(
ExecJs(web_contents(),
JsReplace("const iframe = document.createElement('iframe'); "
"iframe.src = $1; "
"document.body.appendChild(iframe);",
non_isolated_page)));
ASSERT_TRUE(non_coi_iframe_navigation.WaitForNavigationFinished());
EXPECT_TRUE(non_coi_iframe_navigation.was_successful());
RenderFrameHostImpl* non_coi_iframe_rfh =
current_frame_host()->child_at(1)->current_frame_host();
SiteInstanceImpl* non_coi_iframe_si = non_coi_iframe_rfh->GetSiteInstance();
EXPECT_FALSE(non_coi_iframe_si->IsCrossOriginIsolated());
EXPECT_TRUE(non_coi_iframe_si->IsRelatedSiteInstance(main_si));
EXPECT_NE(non_coi_iframe_si, main_si);
EXPECT_NE(non_coi_iframe_si->GetProcess(), main_si->GetProcess());
EXPECT_NE(non_coi_iframe_si, coi_iframe_si);
EXPECT_NE(non_coi_iframe_si->GetProcess(), coi_iframe_si->GetProcess());
TestNavigationManager cross_origin_iframe_navigation(web_contents(),
isolated_page_b);
EXPECT_TRUE(
ExecJs(web_contents(),
JsReplace("const iframe = document.createElement('iframe'); "
"iframe.src = $1; "
"document.body.appendChild(iframe);",
isolated_page_b)));
ASSERT_TRUE(cross_origin_iframe_navigation.WaitForNavigationFinished());
EXPECT_TRUE(cross_origin_iframe_navigation.was_successful());
RenderFrameHostImpl* iframe_rfh =
current_frame_host()->child_at(2)->current_frame_host();
SiteInstanceImpl* cross_origin_iframe_si = iframe_rfh->GetSiteInstance();
EXPECT_TRUE(cross_origin_iframe_si->IsCrossOriginIsolated());
EXPECT_TRUE(cross_origin_iframe_si->IsRelatedSiteInstance(main_si));
EXPECT_NE(cross_origin_iframe_si, main_si);
EXPECT_NE(cross_origin_iframe_si->GetProcess(), main_si->GetProcess());
EXPECT_NE(cross_origin_iframe_si, coi_iframe_si);
EXPECT_NE(cross_origin_iframe_si->GetProcess(), coi_iframe_si->GetProcess());
EXPECT_NE(cross_origin_iframe_si, non_coi_iframe_si);
EXPECT_NE(cross_origin_iframe_si->GetProcess(),
non_coi_iframe_si->GetProcess());
{
scoped_refptr<SiteInstanceImpl> previous_si =
current_frame_host()->GetSiteInstance();
EXPECT_TRUE(NavigateToURLFromRenderer(shell(), non_isolated_page));
main_si = current_frame_host()->GetSiteInstance();
EXPECT_FALSE(main_si->IsCrossOriginIsolated());
EXPECT_NE(main_si->GetProcess(),
previous_si->GetOrCreateProcessForTesting());
if (IsBackForwardCacheEnabled()) {
EXPECT_FALSE(main_si->IsRelatedSiteInstance(previous_si.get()));
} else {
EXPECT_TRUE(main_si->IsRelatedSiteInstance(previous_si.get()));
}
TestNavigationManager same_origin_iframe_navigation(web_contents(),
isolated_page);
EXPECT_TRUE(
ExecJs(web_contents(),
JsReplace("const iframe = document.createElement('iframe'); "
"iframe.src = $1; "
"document.body.appendChild(iframe);",
isolated_page)));
ASSERT_TRUE(same_origin_iframe_navigation.WaitForNavigationFinished());
EXPECT_TRUE(same_origin_iframe_navigation.was_successful());
iframe_rfh = current_frame_host()->child_at(0)->current_frame_host();
SiteInstanceImpl* iframe_si = iframe_rfh->GetSiteInstance();
EXPECT_TRUE(iframe_si->IsCrossOriginIsolated());
EXPECT_TRUE(iframe_si->IsRelatedSiteInstance(main_si));
EXPECT_NE(iframe_si, main_si);
EXPECT_NE(iframe_si->GetProcess(), main_si->GetProcess());
}
}
IN_PROC_BROWSER_TEST_P(DocumentIsolationPolicyBrowserTest,
CrossOriginIsolatedSiteInstance_Popup) {
GURL isolated_page = GetDocumentIsolationPolicyURL("a.test");
GURL isolated_page_b = GetDocumentIsolationPolicyURL("cdn.a.test");
GURL non_isolated_page(
embedded_test_server()->GetURL("a.test", "/title1.html"));
EXPECT_TRUE(NavigateToURL(shell(), isolated_page));
SiteInstanceImpl* main_si = current_frame_host()->GetSiteInstance();
EXPECT_TRUE(main_si->IsCrossOriginIsolated());
{
RenderFrameHostImpl* popup_rfh =
static_cast<WebContentsImpl*>(
OpenPopup(current_frame_host(), non_isolated_page, "")
->web_contents())
->GetPrimaryMainFrame();
EXPECT_FALSE(popup_rfh->GetSiteInstance()->IsCrossOriginIsolated());
EXPECT_TRUE(popup_rfh->GetSiteInstance()->IsRelatedSiteInstance(
current_frame_host()->GetSiteInstance()));
}
{
RenderFrameHostImpl* popup_rfh =
static_cast<WebContentsImpl*>(
OpenPopup(current_frame_host(), isolated_page, "")->web_contents())
->GetPrimaryMainFrame();
EXPECT_TRUE(popup_rfh->GetSiteInstance()->IsCrossOriginIsolated());
EXPECT_EQ(popup_rfh->GetSiteInstance(),
current_frame_host()->GetSiteInstance());
}
{
RenderFrameHostImpl* popup_rfh =
static_cast<WebContentsImpl*>(
OpenPopup(current_frame_host(), isolated_page_b, "")
->web_contents())
->GetPrimaryMainFrame();
EXPECT_TRUE(popup_rfh->GetSiteInstance()->IsCrossOriginIsolated());
EXPECT_TRUE(popup_rfh->GetSiteInstance()->IsRelatedSiteInstance(
current_frame_host()->GetSiteInstance()));
EXPECT_NE(popup_rfh->GetSiteInstance()->GetProcess(),
current_frame_host()->GetSiteInstance()->GetProcess());
}
}
IN_PROC_BROWSER_TEST_P(DocumentIsolationPolicyBrowserTest,
CrossOriginIsolatedSiteInstance_ErrorPage) {
GURL isolated_page = GetDocumentIsolationPolicyURL(
"a.test", "Cross-Origin-Embedder-Policy: require-corp");
GURL non_coep_page(https_server()->GetURL("b.test",
"/set-header?"
"Access-Control-Allow-Origin: *"));
GURL invalid_url(
https_server()->GetURL("a.test", "/this_page_does_not_exist.html"));
GURL error_url(https_server()->GetURL("a.test", "/page404.html"));
GURL non_isolated_page(
https_server()->GetURL("a.test",
"/set-header?"
"Cross-Origin-Embedder-Policy: require-corp"));
EXPECT_TRUE(NavigateToURL(shell(), isolated_page));
SiteInstanceImpl* main_si = current_frame_host()->GetSiteInstance();
EXPECT_TRUE(main_si->IsCrossOriginIsolated());
{
TestNavigationManager iframe_navigation(web_contents(), invalid_url);
EXPECT_TRUE(
ExecJs(web_contents(),
JsReplace("const iframe = document.createElement('iframe'); "
"iframe.src = $1; "
"document.body.appendChild(iframe);",
invalid_url)));
ASSERT_TRUE(iframe_navigation.WaitForNavigationFinished());
EXPECT_FALSE(iframe_navigation.was_successful());
RenderFrameHostImpl* iframe_rfh =
current_frame_host()->child_at(0)->current_frame_host();
SiteInstanceImpl* iframe_si = iframe_rfh->GetSiteInstance();
EXPECT_EQ(GURL(kUnreachableWebDataURL),
EvalJs(iframe_rfh, "document.location.href;"));
EXPECT_TRUE(IsExpectedSubframeErrorTransition(main_si, iframe_si));
EXPECT_FALSE(iframe_si->IsCrossOriginIsolated());
EXPECT_NE(iframe_si, main_si);
}
{
TestNavigationManager iframe_navigation(web_contents(), error_url);
EXPECT_TRUE(
ExecJs(web_contents(),
JsReplace("const iframe = document.createElement('iframe'); "
"iframe.src = $1; "
"document.body.appendChild(iframe);",
error_url)));
ASSERT_TRUE(iframe_navigation.WaitForNavigationFinished());
EXPECT_FALSE(iframe_navigation.was_successful());
RenderFrameHostImpl* iframe_rfh =
current_frame_host()->child_at(0)->current_frame_host();
SiteInstanceImpl* iframe_si = iframe_rfh->GetSiteInstance();
EXPECT_TRUE(IsExpectedSubframeErrorTransition(main_si, iframe_si));
EXPECT_EQ(GURL(kUnreachableWebDataURL),
EvalJs(iframe_rfh, "document.location.href;"));
EXPECT_FALSE(iframe_si->IsCrossOriginIsolated());
EXPECT_NE(iframe_si, main_si);
}
{
TestNavigationManager iframe_navigation(web_contents(), non_coep_page);
EXPECT_TRUE(
ExecJs(web_contents(),
JsReplace("const iframe = document.createElement('iframe'); "
"iframe.src = $1; "
"document.body.appendChild(iframe);",
non_coep_page)));
ASSERT_TRUE(iframe_navigation.WaitForNavigationFinished());
EXPECT_FALSE(iframe_navigation.was_successful());
RenderFrameHostImpl* iframe_rfh =
current_frame_host()->child_at(0)->current_frame_host();
SiteInstanceImpl* iframe_si = iframe_rfh->GetSiteInstance();
EXPECT_TRUE(IsExpectedSubframeErrorTransition(main_si, iframe_si));
EXPECT_FALSE(iframe_si->IsCrossOriginIsolated());
}
{
scoped_refptr<SiteInstanceImpl> previous_si =
current_frame_host()->GetSiteInstance();
EXPECT_FALSE(NavigateToURL(shell(), invalid_url));
SiteInstanceImpl* current_si = current_frame_host()->GetSiteInstance();
if (IsBackForwardCacheEnabled()) {
EXPECT_FALSE(current_si->IsRelatedSiteInstance(previous_si.get()));
} else {
EXPECT_TRUE(current_si->IsRelatedSiteInstance(previous_si.get()));
}
EXPECT_NE(current_si->GetProcess(),
previous_si->GetOrCreateProcessForTesting());
EXPECT_FALSE(current_si->IsCrossOriginIsolated());
}
{
EXPECT_TRUE(NavigateToURL(shell(), non_isolated_page));
SiteInstanceImpl* current_si = current_frame_host()->GetSiteInstance();
EXPECT_FALSE(current_si->IsCrossOriginIsolated());
TestNavigationManager iframe_navigation(web_contents(), isolated_page);
EXPECT_TRUE(
ExecJs(web_contents(),
JsReplace("const iframe = document.createElement('iframe'); "
"iframe.id = 'iframe';"
"iframe.src = $1; "
"document.body.appendChild(iframe);",
isolated_page)));
ASSERT_TRUE(iframe_navigation.WaitForNavigationFinished());
EXPECT_TRUE(iframe_navigation.was_successful());
RenderFrameHostImpl* iframe_rfh =
current_frame_host()->child_at(0)->current_frame_host();
scoped_refptr<SiteInstanceImpl> iframe_si = iframe_rfh->GetSiteInstance();
EXPECT_TRUE(iframe_si->IsCrossOriginIsolated());
EXPECT_NE(current_si, iframe_si);
EXPECT_NE(current_si->GetProcess(), iframe_si->GetProcess());
TestNavigationManager error_navigation(web_contents(), invalid_url);
EXPECT_TRUE(ExecJs(
web_contents(),
JsReplace("document.getElementById('iframe').src = $1;", invalid_url)));
ASSERT_TRUE(error_navigation.WaitForNavigationFinished());
EXPECT_FALSE(error_navigation.was_successful());
iframe_rfh = current_frame_host()->child_at(0)->current_frame_host();
scoped_refptr<SiteInstanceImpl> error_si = iframe_rfh->GetSiteInstance();
EXPECT_FALSE(error_si->IsCrossOriginIsolated());
EXPECT_NE(error_si, iframe_si);
EXPECT_NE(error_si->GetProcess(), iframe_si->GetProcess());
EXPECT_EQ(error_si, current_si);
EXPECT_EQ(error_si->GetProcess(), current_si->GetProcess());
}
}
IN_PROC_BROWSER_TEST_P(DocumentIsolationPolicyBrowserTest,
ReloadRedirectsToDipPage) {
GURL dip_page = GetDocumentIsolationPolicyURL("a.test");
GURL redirect_page(https_server()->GetURL(
"a.test", "/redirect-on-second-navigation?" + dip_page.spec()));
EXPECT_TRUE(NavigateToURL(shell(), redirect_page));
scoped_refptr<SiteInstanceImpl> main_si =
current_frame_host()->GetSiteInstance();
EXPECT_EQ(current_frame_host()->GetLastCommittedURL(), redirect_page);
ReloadBlockUntilNavigationsComplete(shell(), 1);
EXPECT_EQ(current_frame_host()->GetLastCommittedURL(), dip_page);
EXPECT_NE(main_si, current_frame_host()->GetSiteInstance());
EXPECT_TRUE(
main_si->IsRelatedSiteInstance(current_frame_host()->GetSiteInstance()));
EXPECT_NE(main_si->GetOrCreateProcessForTesting(),
current_frame_host()->GetSiteInstance()->GetProcess());
}
IN_PROC_BROWSER_TEST_P(DocumentIsolationPolicyBrowserTest,
ReloadPageWithUpdatedDipHeader) {
GURL changing_dip_page(
https_server()->GetURL("a.test", "/serve-dip-on-second-navigation"));
EXPECT_TRUE(NavigateToURL(shell(), changing_dip_page));
scoped_refptr<SiteInstanceImpl> main_si =
current_frame_host()->GetSiteInstance();
ReloadBlockUntilNavigationsComplete(shell(), 1);
EXPECT_NE(main_si, current_frame_host()->GetSiteInstance());
EXPECT_TRUE(
main_si->IsRelatedSiteInstance(current_frame_host()->GetSiteInstance()));
EXPECT_NE(main_si->GetOrCreateProcessForTesting(),
current_frame_host()->GetSiteInstance()->GetProcess());
}
IN_PROC_BROWSER_TEST_P(DocumentIsolationPolicyBrowserTest,
CrossOriginSameSiteIframe) {
GURL isolated_page = GetDocumentIsolationPolicyURL("a.test");
GURL isolated_page_b = GetDocumentIsolationPolicyURL("cdn.a.test");
EXPECT_TRUE(NavigateToURL(shell(), isolated_page));
SiteInstanceImpl* main_si = current_frame_host()->GetSiteInstance();
EXPECT_TRUE(main_si->IsCrossOriginIsolated());
TestNavigationManager cross_origin_iframe_navigation(web_contents(),
isolated_page_b);
EXPECT_TRUE(
ExecJs(web_contents(),
JsReplace("const iframe = document.createElement('iframe'); "
"iframe.src = $1; "
"document.body.appendChild(iframe);",
isolated_page_b)));
ASSERT_TRUE(cross_origin_iframe_navigation.WaitForNavigationFinished());
EXPECT_TRUE(cross_origin_iframe_navigation.was_successful());
RenderFrameHostImpl* iframe_rfh =
current_frame_host()->child_at(0)->current_frame_host();
SiteInstanceImpl* iframe_si = iframe_rfh->GetSiteInstance();
EXPECT_NE(iframe_si, main_si);
EXPECT_TRUE(iframe_si->IsCrossOriginIsolated());
EXPECT_TRUE(iframe_si->IsRelatedSiteInstance(main_si));
EXPECT_NE(iframe_si->GetProcess(), main_si->GetProcess());
{
RenderFrameHostImpl* popup_rfh =
static_cast<WebContentsImpl*>(
OpenPopup(iframe_rfh, isolated_page, "", "", true)->web_contents())
->GetPrimaryMainFrame();
EXPECT_EQ(main_si, popup_rfh->GetSiteInstance());
}
}
IN_PROC_BROWSER_TEST_P(DocumentIsolationPolicyBrowserTest,
WebExposedIsolationLevel) {
GURL isolated_page = GetDocumentIsolationPolicyURL("a.test");
GURL isolated_page_b = GetDocumentIsolationPolicyURL("b.test");
EXPECT_TRUE(NavigateToURL(shell(), https_server()->GetURL("/empty.html")));
EXPECT_EQ(WebExposedIsolationLevel::kNotIsolated,
current_frame_host()->GetWebExposedIsolationLevel());
EXPECT_TRUE(NavigateToURL(shell(), isolated_page));
EXPECT_EQ(WebExposedIsolationLevel::kIsolated,
current_frame_host()->GetWebExposedIsolationLevel());
std::string create_iframe = R"(
new Promise(resolve => {
const iframe = document.createElement('iframe');
iframe.src = $1;
iframe.allow = "cross-origin-isolated 'none'";
iframe.addEventListener('load', () => resolve(true));
document.body.appendChild(iframe);
});
)";
EXPECT_TRUE(ExecJs(shell(), JsReplace(create_iframe, isolated_page_b)));
RenderFrameHostImpl* iframe_rfh =
current_frame_host()->child_at(0)->current_frame_host();
EXPECT_EQ(WebExposedIsolationLevel::kIsolated,
iframe_rfh->GetWebExposedIsolationLevel());
}
IN_PROC_BROWSER_TEST_P(DocumentIsolationPolicyBrowserTest, SAB) {
GURL url = GetDocumentIsolationPolicyURL("a.test");
EXPECT_TRUE(NavigateToURL(shell(), url));
EXPECT_EQ(true, EvalJs(current_frame_host(), "self.crossOriginIsolated"));
EXPECT_EQ(true,
EvalJs(current_frame_host(), "'SharedArrayBuffer' in globalThis"));
}
IN_PROC_BROWSER_TEST_P(DocumentIsolationPolicyBrowserTest,
SAB_TransferToIframe) {
CHECK(!base::FeatureList::IsEnabled(features::kSharedArrayBuffer));
GURL url = GetDocumentIsolationPolicyURL("a.test");
EXPECT_TRUE(NavigateToURL(shell(), url));
EXPECT_TRUE(ExecJs(current_frame_host(),
"g_iframe = document.createElement('iframe');"
"g_iframe.src = location.href;"
"document.body.appendChild(g_iframe);"));
WaitForLoadStop(web_contents());
RenderFrameHostImpl* main_document = current_frame_host();
RenderFrameHostImpl* sub_document =
current_frame_host()->child_at(0)->current_frame_host();
EXPECT_EQ(true, EvalJs(main_document, "self.crossOriginIsolated"));
EXPECT_EQ(true, EvalJs(sub_document, "self.crossOriginIsolated"));
EXPECT_TRUE(ExecJs(sub_document, R"(
g_sab_size = new Promise(resolve => {
addEventListener("message", event => resolve(event.data.byteLength));
});
)",
EXECUTE_SCRIPT_NO_RESOLVE_PROMISES));
EXPECT_TRUE(ExecJs(main_document, R"(
const sab = new SharedArrayBuffer(1234);
g_iframe.contentWindow.postMessage(sab, "*");
)"));
EXPECT_EQ(1234, EvalJs(sub_document, "g_sab_size"));
}
IN_PROC_BROWSER_TEST_P(DocumentIsolationPolicyBrowserTest,
SAB_TransferToAboutBlankIframe) {
CHECK(!base::FeatureList::IsEnabled(features::kSharedArrayBuffer));
GURL url = GetDocumentIsolationPolicyURL("a.test");
EXPECT_TRUE(NavigateToURL(shell(), url));
EXPECT_TRUE(ExecJs(current_frame_host(),
"g_iframe = document.createElement('iframe');"
"g_iframe.src = 'about:blank';"
"document.body.appendChild(g_iframe);"));
WaitForLoadStop(web_contents());
RenderFrameHostImpl* main_document = current_frame_host();
RenderFrameHostImpl* sub_document =
current_frame_host()->child_at(0)->current_frame_host();
EXPECT_EQ(true, EvalJs(main_document, "self.crossOriginIsolated"));
EXPECT_EQ(true, EvalJs(sub_document, "self.crossOriginIsolated"));
EXPECT_EQ(true, EvalJs(sub_document, "'SharedArrayBuffer' in globalThis"));
}
IN_PROC_BROWSER_TEST_P(DocumentIsolationPolicyBrowserTest,
AboutBlankIsSetCOISynchronously) {
CHECK(!base::FeatureList::IsEnabled(features::kSharedArrayBuffer));
GURL url = GetDocumentIsolationPolicyURL("a.test");
EXPECT_TRUE(NavigateToURL(shell(), url));
EXPECT_EQ(true, EvalJs(current_frame_host(),
"const iframe = document.createElement('iframe');"
"document.body.appendChild(iframe);"
"iframe.contentWindow.crossOriginIsolated;"));
}
IN_PROC_BROWSER_TEST_P(DocumentIsolationPolicyBrowserTest,
SAB_TransferToNoCrossOriginIsolatedIframe) {
CHECK(!base::FeatureList::IsEnabled(features::kSharedArrayBuffer));
GURL main_url = GetDocumentIsolationPolicyURL("a.test");
GURL iframe_url = https_server()->GetURL("a.test", "/title1.html");
EXPECT_TRUE(NavigateToURL(shell(), main_url));
EXPECT_TRUE(ExecJs(current_frame_host(),
JsReplace("g_iframe = document.createElement('iframe');"
"g_iframe.src = $1;"
"document.body.appendChild(g_iframe);",
iframe_url)));
WaitForLoadStop(web_contents());
RenderFrameHostImpl* main_document = current_frame_host();
RenderFrameHostImpl* sub_document =
current_frame_host()->child_at(0)->current_frame_host();
EXPECT_EQ(true, EvalJs(main_document, "self.crossOriginIsolated"));
EXPECT_EQ(false, EvalJs(sub_document, "self.crossOriginIsolated"));
EXPECT_NE(main_document->GetSiteInstance()->GetProcess(),
sub_document->GetSiteInstance()->GetProcess());
}
IN_PROC_BROWSER_TEST_P(DocumentIsolationPolicyBrowserTest,
SAB_TransferFromNoCrossOriginIsolatedIframe) {
CHECK(!base::FeatureList::IsEnabled(features::kSharedArrayBuffer));
GURL main_url = GetDocumentIsolationPolicyURL("a.test");
GURL iframe_url = https_server()->GetURL("a.test", "/title1.html");
EXPECT_TRUE(NavigateToURL(shell(), main_url));
EXPECT_TRUE(ExecJs(current_frame_host(),
JsReplace("g_iframe = document.createElement('iframe');"
"g_iframe.src = $1;"
"document.body.appendChild(g_iframe);",
iframe_url)));
WaitForLoadStop(web_contents());
RenderFrameHostImpl* main_document = current_frame_host();
RenderFrameHostImpl* sub_document =
current_frame_host()->child_at(0)->current_frame_host();
EXPECT_EQ(true, EvalJs(main_document, "self.crossOriginIsolated"));
EXPECT_EQ(false, EvalJs(sub_document, "self.crossOriginIsolated"));
EXPECT_TRUE(ExecJs(main_document, R"(
g_sab_size = new Promise(resolve => {
addEventListener("message", event => resolve(event.data.byteLength));
});
)",
EXECUTE_SCRIPT_NO_RESOLVE_PROMISES));
EXPECT_EQ(false, EvalJs(sub_document, "'SharedArrayBuffer' in globalThis"));
EXPECT_FALSE(ExecJs(sub_document, R"(
// Create a WebAssembly Memory to try to bypass the SAB constructor
// restriction.
const sab = new (new WebAssembly.Memory(
{ shared:true, initial:1, maximum:1 }).buffer.constructor)(1234);
parent.postMessage(sab, "*");
)"));
}
IN_PROC_BROWSER_TEST_P(DocumentIsolationPolicyBrowserTest,
CrossOriginIsolatedIframe_SameOrigin) {
CHECK(!base::FeatureList::IsEnabled(features::kSharedArrayBuffer));
GURL main_url = https_server()->GetURL("a.test", "/title1.html");
GURL iframe_url = GetDocumentIsolationPolicyURL("a.test");
EXPECT_TRUE(NavigateToURL(shell(), main_url));
EXPECT_TRUE(ExecJs(current_frame_host(),
JsReplace("g_iframe = document.createElement('iframe');"
"g_iframe.src = $1;"
"document.body.appendChild(g_iframe);",
iframe_url)));
WaitForLoadStop(web_contents());
RenderFrameHostImpl* main_document = current_frame_host();
RenderFrameHostImpl* sub_document =
current_frame_host()->child_at(0)->current_frame_host();
EXPECT_EQ(false, EvalJs(main_document, "self.crossOriginIsolated"));
EXPECT_EQ(true, EvalJs(sub_document, "self.crossOriginIsolated"));
EXPECT_NE(main_document->GetSiteInstance()->GetProcess(),
sub_document->GetSiteInstance()->GetProcess());
}
IN_PROC_BROWSER_TEST_P(DocumentIsolationPolicyBrowserTest,
CrossOriginIsolatedIframe_CrossOrigin) {
CHECK(!base::FeatureList::IsEnabled(features::kSharedArrayBuffer));
GURL main_url = https_server()->GetURL("a.test", "/title1.html");
GURL iframe_url = GetDocumentIsolationPolicyURL("b.test");
EXPECT_TRUE(NavigateToURL(shell(), main_url));
EXPECT_TRUE(ExecJs(current_frame_host(),
JsReplace("g_iframe = document.createElement('iframe');"
"g_iframe.src = $1;"
"document.body.appendChild(g_iframe);",
iframe_url)));
WaitForLoadStop(web_contents());
RenderFrameHostImpl* main_document = current_frame_host();
RenderFrameHostImpl* sub_document =
current_frame_host()->child_at(0)->current_frame_host();
EXPECT_EQ(false, EvalJs(main_document, "self.crossOriginIsolated"));
EXPECT_EQ(true, EvalJs(sub_document, "self.crossOriginIsolated"));
EXPECT_NE(main_document->GetSiteInstance()->GetProcess(),
sub_document->GetSiteInstance()->GetProcess());
}
IN_PROC_BROWSER_TEST_P(DocumentIsolationPolicyBrowserTest,
DIPNavigationToLocalScheme) {
GURL main_url = GetDocumentIsolationPolicyURL("a.test");
EXPECT_TRUE(NavigateToURL(shell(), main_url));
EXPECT_TRUE(ExecJs(current_frame_host(), "location = 'about:blank';"));
EXPECT_TRUE(WaitForLoadStop(web_contents()));
EXPECT_EQ(url::kAboutBlankURL, current_frame_host()->GetLastCommittedURL());
EXPECT_EQ(current_frame_host()
->policy_container_host()
->policies()
.document_isolation_policy,
GetDocumentIsolationPolicy());
}
IN_PROC_BROWSER_TEST_P(DocumentIsolationPolicyBrowserTest,
IframeLoadCancelledInBeginNavigation) {
GURL main_url = GetDocumentIsolationPolicyURL(
"a.test", "Content-Security-Policy: frame-src 'none';");
GURL iframe_url = https_server()->GetURL("a.test", "/title1.html");
EXPECT_TRUE(NavigateToURL(shell(), main_url));
EXPECT_TRUE(ExecJs(current_frame_host(),
JsReplace("g_iframe = document.createElement('iframe');"
"g_iframe.src = $1;"
"document.body.appendChild(g_iframe);",
iframe_url)));
WaitForLoadStop(web_contents());
RenderFrameHostImpl* main_document = current_frame_host();
RenderFrameHostImpl* sub_document =
current_frame_host()->child_at(0)->current_frame_host();
EXPECT_EQ(main_document->GetSiteInstance()->GetProcess(),
sub_document->GetSiteInstance()->GetProcess());
EXPECT_FALSE(sub_document->GetSiteInstance()->GetSiteInfo().is_error_page());
}
static auto kTestParams =
testing::Combine(testing::ValuesIn(RenderDocumentFeatureLevelValues()),
testing::Bool(),
testing::Bool());
INSTANTIATE_TEST_SUITE_P(All,
DocumentIsolationPolicyBrowserTest,
kTestParams,
DocumentIsolationPolicyBrowserTest::DescribeParams);
INSTANTIATE_TEST_SUITE_P(All,
DocumentIsolationPolicyWithoutFeatureBrowserTest,
kTestParams,
DocumentIsolationPolicyBrowserTest::DescribeParams);
INSTANTIATE_TEST_SUITE_P(All,
DocumentIsolationPolicyWithoutSiteIsolationBrowserTest,
kTestParams,
DocumentIsolationPolicyBrowserTest::DescribeParams);
}