#include "content/browser/site_per_process_browsertest.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/site_isolation_policy.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.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/test_frame_navigation_observer.h"
#include "content/test/render_document_feature.h"
#include "net/dns/mock_host_resolver.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/switches.h"
namespace content {
class BaseUrlInheritanceBehaviorIframeTest : public ContentBrowserTest {
public:
BaseUrlInheritanceBehaviorIframeTest() {
feature_list_.InitAndEnableFeature(
blink::features::kNewBaseUrlInheritanceBehavior);
}
void SetUpOnMainThread() override {
host_resolver()->AddRule("*", "127.0.0.1");
}
void StartEmbeddedServer() {
SetupCrossSiteRedirector(embedded_test_server());
ASSERT_TRUE(embedded_test_server()->Start());
}
private:
base::test::ScopedFeatureList feature_list_;
};
class SrcdocIsolatedSandboxedIframeTest
: public ContentBrowserTest,
public ::testing::WithParamInterface<bool> {
public:
SrcdocIsolatedSandboxedIframeTest() {
feature_list_.InitWithFeatureState(
blink::features::kIsolateSandboxedIframes, GetParam());
}
void SetUpOnMainThread() override {
host_resolver()->AddRule("*", "127.0.0.1");
}
void StartEmbeddedServer() {
SetupCrossSiteRedirector(embedded_test_server());
ASSERT_TRUE(embedded_test_server()->Start());
}
private:
base::test::ScopedFeatureList feature_list_;
};
class BaseUrlInheritanceBehaviorEnterprisePolicyTest
: public SrcdocIsolatedSandboxedIframeTest {
public:
BaseUrlInheritanceBehaviorEnterprisePolicyTest() = default;
void SetUpCommandLine(base::CommandLine* command_line) override {
SrcdocIsolatedSandboxedIframeTest::SetUpCommandLine(command_line);
command_line->AppendSwitch(
blink::switches::kDisableNewBaseUrlInheritanceBehavior);
}
};
class SitePerProcessIsolatedSandboxedIframeTest
: public SitePerProcessBrowserTest {
public:
SitePerProcessIsolatedSandboxedIframeTest() {
feature_list_.InitAndEnableFeature(
blink::features::kIsolateSandboxedIframes);
}
private:
base::test::ScopedFeatureList feature_list_;
};
class SitePerProcessNotIsolatedSandboxedIframeTest
: public SitePerProcessBrowserTest {
public:
SitePerProcessNotIsolatedSandboxedIframeTest() {
feature_list_.InitAndDisableFeature(
blink::features::kIsolateSandboxedIframes);
}
private:
base::test::ScopedFeatureList feature_list_;
};
class SitePerProcessPerOriginIsolatedSandboxedIframeTest
: public SitePerProcessBrowserTest {
public:
SitePerProcessPerOriginIsolatedSandboxedIframeTest() {
feature_list_.InitWithFeaturesAndParameters(
{{blink::features::kIsolateSandboxedIframes,
{{"grouping", "per-origin"}}}},
{});
}
private:
base::test::ScopedFeatureList feature_list_;
};
class SitePerProcessIsolatedSandboxWithoutStrictSiteIsolationBrowserTest
: public SitePerProcessIsolatedSandboxedIframeTest {
public:
SitePerProcessIsolatedSandboxWithoutStrictSiteIsolationBrowserTest() {
feature_list_.InitAndEnableFeature(
blink::features::kIsolateSandboxedIframes);
}
void SetUpCommandLine(base::CommandLine* command_line) override {
SitePerProcessIsolatedSandboxedIframeTest::SetUpCommandLine(command_line);
command_line->RemoveSwitch(switches::kSitePerProcess);
}
void SetUpOnMainThread() override {
SitePerProcessIsolatedSandboxedIframeTest::SetUpOnMainThread();
browser_client_ =
std::make_unique<PartialSiteIsolationContentBrowserClient>();
if (AreAllSitesIsolatedForTesting()) {
LOG(WARNING) << "This test should be run without --site-per-process, "
<< "as it's designed to exercise code paths when strict "
<< "site isolation is turned off.";
}
}
void TearDownOnMainThread() override {
SitePerProcessIsolatedSandboxedIframeTest::TearDownOnMainThread();
browser_client_.reset();
}
class PartialSiteIsolationContentBrowserClient
: public ContentBrowserTestContentBrowserClient {
public:
bool ShouldEnableStrictSiteIsolation() override { return false; }
bool DoesSiteRequireDedicatedProcess(
BrowserContext* browser_context,
const GURL& effective_site_url) override {
return effective_site_url == GURL("http://isolated.com");
}
};
private:
base::test::ScopedFeatureList feature_list_;
std::unique_ptr<PartialSiteIsolationContentBrowserClient> browser_client_;
};
class SitePerProcessPerDocumentIsolatedSandboxedIframeTest
: public SitePerProcessBrowserTest {
public:
SitePerProcessPerDocumentIsolatedSandboxedIframeTest() {
feature_list_.InitWithFeaturesAndParameters(
{{blink::features::kIsolateSandboxedIframes,
{{"grouping", "per-document"}}}},
{});
}
private:
base::test::ScopedFeatureList feature_list_;
};
IN_PROC_BROWSER_TEST_P(SitePerProcessNotIsolatedSandboxedIframeTest,
SrcdocSandboxFlagsCheck) {
GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
EXPECT_TRUE(ExecJs(shell(),
"var frame = document.createElement('iframe'); "
"frame.csp = 'sandbox'; "
"frame.srcdoc = 'foo'; "
"document.body.appendChild(frame);"));
ASSERT_TRUE(WaitForLoadStop(web_contents()));
}
IN_PROC_BROWSER_TEST_P(SitePerProcessIsolatedSandboxedIframeTest,
SrcdocCspSandboxIsIsolated) {
GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
EXPECT_TRUE(ExecJs(shell(),
"var frame = document.createElement('iframe'); "
"frame.csp = 'sandbox'; "
"frame.srcdoc = 'foo'; "
"document.body.appendChild(frame);"));
ASSERT_TRUE(WaitForLoadStop(web_contents()));
FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
ASSERT_EQ(1U, root->child_count());
FrameTreeNode* child = root->child_at(0);
EXPECT_EQ(network::mojom::WebSandboxFlags::kAll,
child->current_frame_host()->active_sandbox_flags());
EXPECT_NE(root->current_frame_host()->GetSiteInstance(),
child->current_frame_host()->GetSiteInstance());
EXPECT_TRUE(child->current_frame_host()
->GetSiteInstance()
->GetSiteInfo()
.is_sandboxed());
EXPECT_FALSE(root->current_frame_host()
->GetSiteInstance()
->GetSiteInfo()
.is_sandboxed());
}
IN_PROC_BROWSER_TEST_P(SitePerProcessIsolatedSandboxedIframeTest,
CspIsolatedSandbox) {
GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
GURL child_url(main_url);
EXPECT_TRUE(NavigateToURL(shell(), main_url));
{
std::string js_str = base::StringPrintf(
"var frame = document.createElement('iframe'); "
"frame.csp = 'sandbox'; "
"frame.src = '%s'; "
"document.body.appendChild(frame);",
child_url.spec().c_str());
EXPECT_TRUE(ExecJs(shell(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
ASSERT_EQ(1U, root->child_count());
FrameTreeNode* child = root->child_at(0);
EXPECT_EQ(network::mojom::WebSandboxFlags::kAll,
child->current_frame_host()->active_sandbox_flags());
EXPECT_NE(root->current_frame_host()->GetSiteInstance(),
child->current_frame_host()->GetSiteInstance());
EXPECT_TRUE(child->current_frame_host()
->GetSiteInstance()
->GetSiteInfo()
.is_sandboxed());
EXPECT_FALSE(root->current_frame_host()
->GetSiteInstance()
->GetSiteInfo()
.is_sandboxed());
}
IN_PROC_BROWSER_TEST_P(SitePerProcessIsolatedSandboxedIframeTest,
IsolatedSandbox) {
GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
GURL child_url(main_url);
EXPECT_TRUE(NavigateToURL(shell(), main_url));
{
std::string js_str = base::StringPrintf(
"var frame = document.createElement('iframe'); "
"frame.sandbox = ''; "
"frame.src = '%s'; "
"document.body.appendChild(frame);",
child_url.spec().c_str());
EXPECT_TRUE(ExecJs(shell(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
ASSERT_EQ(1U, root->child_count());
FrameTreeNode* child = root->child_at(0);
EXPECT_EQ(network::mojom::WebSandboxFlags::kAll,
child->effective_frame_policy().sandbox_flags);
EXPECT_NE(root->current_frame_host()->GetSiteInstance(),
child->current_frame_host()->GetSiteInstance());
EXPECT_TRUE(child->current_frame_host()
->GetSiteInstance()
->GetSiteInfo()
.is_sandboxed());
EXPECT_FALSE(root->current_frame_host()
->GetSiteInstance()
->GetSiteInfo()
.is_sandboxed());
}
IN_PROC_BROWSER_TEST_P(SitePerProcessPerOriginIsolatedSandboxedIframeTest,
SrcdocSandboxedFrameWithNonSiteParent) {
GURL main_url(embedded_test_server()->GetURL("sub.a.com", "/title1.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
{
std::string js_str =
"const frame = document.createElement('iframe'); "
"frame.sandbox = ''; "
"frame.srcdoc = 'foo'; "
"document.body.appendChild(frame);";
EXPECT_TRUE(ExecJs(shell(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
ASSERT_EQ(1U, root->child_count());
FrameTreeNode* child = root->child_at(0);
EXPECT_EQ(network::mojom::WebSandboxFlags::kAll,
child->effective_frame_policy().sandbox_flags);
auto* parent_site_instance = root->current_frame_host()->GetSiteInstance();
auto* child_site_instance = child->current_frame_host()->GetSiteInstance();
EXPECT_NE(parent_site_instance, child_site_instance);
EXPECT_TRUE(child_site_instance->GetSiteInfo().is_sandboxed());
EXPECT_FALSE(parent_site_instance->GetSiteInfo().is_sandboxed());
EXPECT_EQ(embedded_test_server()->GetURL("sub.a.com", "/"),
child_site_instance->GetSiteInfo().site_url());
EXPECT_EQ(GURL("http://a.com/"),
parent_site_instance->GetSiteInfo().site_url());
}
namespace {
GURL GetFrameBaseUrl(RenderFrameHostImpl* rfhi) {
return GURL(EvalJs(rfhi, "document.baseURI").ExtractString());
}
GURL GetFrameBaseUrl(Shell* shell) {
return GURL(EvalJs(shell, "document.baseURI").ExtractString());
}
}
IN_PROC_BROWSER_TEST_P(SitePerProcessPerOriginIsolatedSandboxedIframeTest,
SrcdocSandboxedFrameInsideAboutBlank) {
GURL main_url(embedded_test_server()->GetURL("a.foo.com", "/title1.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
{
std::string js_str =
"const frame = document.createElement('iframe'); "
"frame.src = 'about:blank'; "
"document.body.appendChild(frame);";
EXPECT_TRUE(ExecJs(shell(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
ASSERT_EQ(1U, root->child_count());
FrameTreeNode* child = root->child_at(0);
{
std::string js_str =
"const frame = document.createElement('iframe'); "
"frame.sandbox = 'allow-scripts'; "
"frame.srcdoc = 'foo'; "
"document.body.appendChild(frame);";
EXPECT_TRUE(ExecJs(child, js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
ASSERT_EQ(1U, child->child_count());
FrameTreeNode* grand_child = child->child_at(0);
auto* grand_child_site_instance =
grand_child->current_frame_host()->GetSiteInstance();
EXPECT_TRUE(grand_child_site_instance->GetSiteInfo().is_sandboxed());
EXPECT_EQ(embedded_test_server()->GetURL("a.foo.com", "/"),
grand_child_site_instance->GetSiteInfo().site_url());
EXPECT_EQ(main_url, GetFrameBaseUrl(grand_child->current_frame_host()));
EXPECT_EQ(main_url, grand_child->current_frame_host()->GetInheritedBaseUrl());
}
IN_PROC_BROWSER_TEST_P(SitePerProcessPerOriginIsolatedSandboxedIframeTest,
SrcdocSandboxedFrameWithNonSiteParent2) {
GURL main_url(embedded_test_server()->GetURL("a.foo.com", "/title1.html"));
GURL sibling_url(embedded_test_server()->GetURL("b.foo.com", "/title1.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
Shell* new_shell = OpenPopup(root, sibling_url, "");
FrameTreeNode* sibling =
static_cast<WebContentsImpl*>(new_shell->web_contents())
->GetPrimaryFrameTree()
.root();
EXPECT_EQ(root->current_frame_host()->GetSiteInstance(),
sibling->current_frame_host()->GetSiteInstance());
{
std::string js_str =
"const frame = document.createElement('iframe'); "
"frame.sandbox = ''; "
"frame.srcdoc = 'foo'; "
"document.body.appendChild(frame);";
EXPECT_TRUE(ExecJs(new_shell, js_str));
ASSERT_TRUE(WaitForLoadStop(new_shell->web_contents()));
}
ASSERT_EQ(1U, sibling->child_count());
FrameTreeNode* child = sibling->child_at(0);
EXPECT_EQ(network::mojom::WebSandboxFlags::kAll,
child->effective_frame_policy().sandbox_flags);
auto* sibling_site_instance =
sibling->current_frame_host()->GetSiteInstance();
auto* child_site_instance = child->current_frame_host()->GetSiteInstance();
EXPECT_NE(sibling_site_instance, child_site_instance);
EXPECT_TRUE(child_site_instance->GetSiteInfo().is_sandboxed());
EXPECT_FALSE(sibling_site_instance->GetSiteInfo().is_sandboxed());
EXPECT_EQ(embedded_test_server()->GetURL("b.foo.com", "/"),
child_site_instance->GetSiteInfo().site_url());
EXPECT_EQ(GURL("http://foo.com/"),
sibling_site_instance->GetSiteInfo().site_url());
}
IN_PROC_BROWSER_TEST_P(SitePerProcessPerOriginIsolatedSandboxedIframeTest,
CrossOriginIsolatedSandboxedIframes) {
GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
GURL same_origin_child_url(main_url);
GURL cross_origin_child_url(
embedded_test_server()->GetURL("sub.a.com", "/title1.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
{
std::string js_str = base::StringPrintf(
"var frame1 = document.createElement('iframe'); "
"frame1.sandbox = ''; "
"frame1.src = '%s'; "
"document.body.appendChild(frame1); "
"var frame2 = document.createElement('iframe'); "
"frame2.sandbox = ''; "
"frame2.src = '%s'; "
"document.body.appendChild(frame2);",
same_origin_child_url.spec().c_str(),
cross_origin_child_url.spec().c_str());
EXPECT_TRUE(ExecJs(shell(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
ASSERT_EQ(2U, root->child_count());
FrameTreeNode* child1 = root->child_at(0);
EXPECT_EQ(network::mojom::WebSandboxFlags::kAll,
child1->effective_frame_policy().sandbox_flags);
EXPECT_NE(root->current_frame_host()->GetSiteInstance(),
child1->current_frame_host()->GetSiteInstance());
EXPECT_TRUE(child1->current_frame_host()
->GetSiteInstance()
->GetSiteInfo()
.is_sandboxed());
EXPECT_FALSE(root->current_frame_host()
->GetSiteInstance()
->GetSiteInfo()
.is_sandboxed());
FrameTreeNode* child2 = root->child_at(1);
EXPECT_EQ(network::mojom::WebSandboxFlags::kAll,
child2->effective_frame_policy().sandbox_flags);
EXPECT_NE(root->current_frame_host()->GetSiteInstance(),
child2->current_frame_host()->GetSiteInstance());
EXPECT_TRUE(child2->current_frame_host()
->GetSiteInstance()
->GetSiteInfo()
.is_sandboxed());
auto* child1_site_instance1 = child1->current_frame_host()->GetSiteInstance();
auto* child2_site_instance1 = child2->current_frame_host()->GetSiteInstance();
EXPECT_NE(child1_site_instance1, child2_site_instance1);
EXPECT_NE(child1_site_instance1->GetProcess(),
child2_site_instance1->GetProcess());
}
IN_PROC_BROWSER_TEST_P(SitePerProcessPerOriginIsolatedSandboxedIframeTest,
CrossOriginNavigationSwitchesSiteInstances) {
GURL main_url(embedded_test_server()->GetURL("foo.com", "/title1.html"));
GURL cross_origin_child_url(
embedded_test_server()->GetURL("a.foo.com", "/title1.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
{
std::string js_str = base::StringPrintf(
"var frame = document.createElement('iframe'); "
"frame.id = 'test_frame'; "
"frame.sandbox = ''; "
"frame.src = '%s'; "
"document.body.appendChild(frame);",
cross_origin_child_url.spec().c_str());
EXPECT_TRUE(ExecJs(shell(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
ASSERT_EQ(1U, root->child_count());
FrameTreeNode* child = root->child_at(0);
EXPECT_EQ(network::mojom::WebSandboxFlags::kAll,
child->effective_frame_policy().sandbox_flags);
scoped_refptr<SiteInstanceImpl> site_instance_root =
root->current_frame_host()->GetSiteInstance();
scoped_refptr<SiteInstanceImpl> site_instance1 =
child->current_frame_host()->GetSiteInstance();
EXPECT_NE(site_instance_root, site_instance1);
EXPECT_TRUE(site_instance1->GetSiteInfo().is_sandboxed());
EXPECT_FALSE(site_instance_root->GetSiteInfo().is_sandboxed());
EXPECT_TRUE(NavigateIframeToURL(
shell()->web_contents(), "test_frame",
GURL(embedded_test_server()->GetURL("b.foo.com", "/title1.html"))));
scoped_refptr<SiteInstanceImpl> site_instance2 =
child->current_frame_host()->GetSiteInstance();
EXPECT_NE(site_instance_root, site_instance2);
EXPECT_NE(site_instance1, site_instance2);
EXPECT_NE(site_instance1->GetProcess(), site_instance2->GetProcess());
}
IN_PROC_BROWSER_TEST_P(SitePerProcessPerOriginIsolatedSandboxedIframeTest,
CrossOriginNavigationToCSPSwitchesSiteInstances) {
GURL main_url(embedded_test_server()->GetURL("foo.com", "/title1.html"));
GURL cross_origin_child_url(
embedded_test_server()->GetURL("a.foo.com", "/title1.html"));
GURL cross_origin_csp_child_url(
embedded_test_server()->GetURL("b.foo.com",
"/set-header?"
"Content-Security-Policy: sandbox "));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
{
std::string js_str = base::StringPrintf(
"var frame = document.createElement('iframe'); "
"frame.id = 'test_frame'; "
"frame.src = '%s'; "
"document.body.appendChild(frame);",
cross_origin_child_url.spec().c_str());
EXPECT_TRUE(ExecJs(shell(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
ASSERT_EQ(1U, root->child_count());
FrameTreeNode* child = root->child_at(0);
scoped_refptr<SiteInstanceImpl> site_instance_root =
root->current_frame_host()->GetSiteInstance();
scoped_refptr<SiteInstanceImpl> site_instance1 =
child->current_frame_host()->GetSiteInstance();
EXPECT_EQ(site_instance_root, site_instance1);
EXPECT_FALSE(site_instance1->GetSiteInfo().is_sandboxed());
EXPECT_TRUE(NavigateIframeToURL(shell()->web_contents(), "test_frame",
cross_origin_csp_child_url));
scoped_refptr<SiteInstanceImpl> site_instance2 =
child->current_frame_host()->GetSiteInstance();
EXPECT_NE(site_instance1, site_instance2);
EXPECT_NE(site_instance1->GetProcess(), site_instance2->GetProcess());
EXPECT_TRUE(site_instance2->GetSiteInfo().is_sandboxed());
}
IN_PROC_BROWSER_TEST_P(SitePerProcessIsolatedSandboxedIframeTest,
SandboxProcessReuse) {
GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
GURL child_url(main_url);
EXPECT_TRUE(NavigateToURL(shell(), main_url));
std::string js_str = base::StringPrintf(
"var frame = document.createElement('iframe'); "
"frame.sandbox = ''; "
"frame.src = '%s'; "
"document.body.appendChild(frame);",
child_url.spec().c_str());
EXPECT_TRUE(ExecJs(shell(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
ASSERT_EQ(1U, root->child_count());
FrameTreeNode* child = root->child_at(0);
EXPECT_EQ(network::mojom::WebSandboxFlags::kAll,
child->effective_frame_policy().sandbox_flags);
EXPECT_NE(root->current_frame_host()->GetSiteInstance(),
child->current_frame_host()->GetSiteInstance());
EXPECT_TRUE(child->current_frame_host()
->GetSiteInstance()
->GetSiteInfo()
.is_sandboxed());
EXPECT_FALSE(root->current_frame_host()
->GetSiteInstance()
->GetSiteInfo()
.is_sandboxed());
Shell* new_shell = CreateBrowser();
EXPECT_TRUE(NavigateToURL(new_shell, main_url));
FrameTreeNode* new_root =
static_cast<WebContentsImpl*>(new_shell->web_contents())
->GetPrimaryFrameTree()
.root();
EXPECT_TRUE(ExecJs(new_shell, js_str));
ASSERT_TRUE(WaitForLoadStop(new_shell->web_contents()));
FrameTreeNode* new_child = new_root->child_at(0);
EXPECT_TRUE(new_child->current_frame_host()
->GetSiteInstance()
->GetSiteInfo()
.is_sandboxed());
EXPECT_FALSE(new_root->current_frame_host()
->GetSiteInstance()
->GetSiteInfo()
.is_sandboxed());
EXPECT_FALSE(
new_child->current_frame_host()->GetSiteInstance()->IsRelatedSiteInstance(
child->current_frame_host()->GetSiteInstance()));
EXPECT_EQ(new_child->current_frame_host()->GetProcess(),
child->current_frame_host()->GetProcess());
}
IN_PROC_BROWSER_TEST_P(SitePerProcessIsolatedSandboxedIframeTest,
IsolatedSandboxSiblingSubframes) {
GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
GURL child_url(main_url);
EXPECT_TRUE(NavigateToURL(shell(), main_url));
{
std::string js_str = base::StringPrintf(
"var frame1 = document.createElement('iframe'); "
"frame1.sandbox = ''; "
"frame1.src = '%s'; "
"document.body.appendChild(frame1); "
"var frame2 = document.createElement('iframe'); "
"frame2.sandbox = ''; "
"frame2.src = '%s'; "
"document.body.appendChild(frame2);",
child_url.spec().c_str(), child_url.spec().c_str());
EXPECT_TRUE(ExecJs(shell(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
ASSERT_EQ(2U, root->child_count());
FrameTreeNode* child1 = root->child_at(0);
FrameTreeNode* child2 = root->child_at(1);
EXPECT_EQ(network::mojom::WebSandboxFlags::kAll,
child1->effective_frame_policy().sandbox_flags);
EXPECT_EQ(network::mojom::WebSandboxFlags::kAll,
child2->effective_frame_policy().sandbox_flags);
EXPECT_NE(root->current_frame_host()->GetSiteInstance(),
child1->current_frame_host()->GetSiteInstance());
EXPECT_NE(root->current_frame_host()->GetSiteInstance(),
child2->current_frame_host()->GetSiteInstance());
EXPECT_EQ(child1->current_frame_host()->GetSiteInstance(),
child2->current_frame_host()->GetSiteInstance());
EXPECT_TRUE(child1->current_frame_host()
->GetSiteInstance()
->GetSiteInfo()
.is_sandboxed());
EXPECT_TRUE(child2->current_frame_host()
->GetSiteInstance()
->GetSiteInfo()
.is_sandboxed());
EXPECT_FALSE(root->current_frame_host()
->GetSiteInstance()
->GetSiteInfo()
.is_sandboxed());
}
IN_PROC_BROWSER_TEST_P(SitePerProcessIsolatedSandboxedIframeTest,
IsolatedSandboxSrcdocSubframe) {
GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
std::string child_inner_text("srcdoc sandboxed subframe");
{
std::string js_str = base::StringPrintf(
"var frame = document.createElement('iframe'); "
"frame.sandbox = 'allow-scripts'; "
"frame.srcdoc = '%s'; "
"document.body.appendChild(frame);",
child_inner_text.c_str());
EXPECT_TRUE(ExecJs(shell(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
ASSERT_EQ(1U, root->child_count());
FrameTreeNode* child = root->child_at(0);
EXPECT_EQ(child->effective_frame_policy().sandbox_flags,
network::mojom::WebSandboxFlags::kAll &
~network::mojom::WebSandboxFlags::kScripts &
~network::mojom::WebSandboxFlags::kAutomaticFeatures);
EXPECT_EQ(std::string(url::kAboutSrcdocURL),
child->current_frame_host()->GetLastCommittedURL());
EXPECT_TRUE(child->current_frame_host()->GetLastCommittedOrigin().opaque());
EXPECT_EQ(url::SchemeHostPort(main_url),
child->current_origin().GetTupleOrPrecursorTupleIfOpaque());
EXPECT_NE(root->current_frame_host()->GetSiteInstance(),
child->current_frame_host()->GetSiteInstance());
EXPECT_TRUE(child->current_frame_host()
->GetSiteInstance()
->GetSiteInfo()
.is_sandboxed());
EXPECT_FALSE(root->current_frame_host()
->GetSiteInstance()
->GetSiteInfo()
.is_sandboxed());
{
std::string js_str("document.body.innerText;");
EXPECT_EQ(child_inner_text, EvalJs(child->current_frame_host(), js_str));
}
}
IN_PROC_BROWSER_TEST_P(SitePerProcessIsolatedSandboxedIframeTest,
NotIsolatedSandboxAboutBlankSubframe) {
GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
{
std::string js_str(
"var frame = document.createElement('iframe'); "
"frame.id = 'child_frame'; "
"frame.sandbox = ''; "
"frame.src = 'about:blank'; "
"document.body.appendChild(frame);");
EXPECT_TRUE(ExecJs(shell(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
ASSERT_EQ(1U, root->child_count());
FrameTreeNode* child = root->child_at(0);
EXPECT_EQ(child->effective_frame_policy().sandbox_flags,
network::mojom::WebSandboxFlags::kAll);
EXPECT_EQ(GURL(url::kAboutBlankURL),
child->current_frame_host()->GetLastCommittedURL());
EXPECT_TRUE(child->current_frame_host()->GetLastCommittedOrigin().opaque());
EXPECT_EQ(url::SchemeHostPort(main_url),
child->current_origin().GetTupleOrPrecursorTupleIfOpaque());
EXPECT_EQ(root->current_frame_host()->GetSiteInstance(),
child->current_frame_host()->GetSiteInstance());
EXPECT_FALSE(root->current_frame_host()
->GetSiteInstance()
->GetSiteInfo()
.is_sandboxed());
GURL isolated_child_url(
embedded_test_server()->GetURL("a.com", "/title1.html"));
EXPECT_TRUE(NavigateFrameToURL(child, isolated_child_url));
EXPECT_NE(root->current_frame_host()->GetSiteInstance(),
child->current_frame_host()->GetSiteInstance());
EXPECT_TRUE(child->current_frame_host()
->GetSiteInstance()
->GetSiteInfo()
.is_sandboxed());
scoped_refptr<SiteInstanceImpl> child_previous_site_instance =
child->current_frame_host()->GetSiteInstance();
EXPECT_TRUE(NavigateIframeToURL(shell()->web_contents(), "child_frame",
GURL("about:blank")));
EXPECT_EQ(root->current_frame_host()->GetSiteInstance(),
child->current_frame_host()->GetSiteInstance());
EXPECT_NE(child_previous_site_instance,
child->current_frame_host()->GetSiteInstance());
EXPECT_FALSE(child->current_frame_host()
->GetSiteInstance()
->GetSiteInfo()
.is_sandboxed());
}
IN_PROC_BROWSER_TEST_P(SitePerProcessIsolatedSandboxedIframeTest,
SandboxedIframeWithJSUrl) {
GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
std::string js_url_str("javascript:\"foo\"");
{
std::string js_str = base::StringPrintf(
"var frame = document.createElement('iframe'); "
"frame.id = 'test_frame'; "
"frame.sandbox = 'allow-scripts'; "
"frame.src = '%s'; "
"document.body.appendChild(frame);",
js_url_str.c_str());
EXPECT_TRUE(ExecJs(shell(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
ASSERT_EQ(1U, root->child_count());
FrameTreeNode* child = root->child_at(0);
EXPECT_EQ(root->current_frame_host()->GetSiteInstance(),
child->current_frame_host()->GetSiteInstance());
EXPECT_TRUE(
EvalJs(child->current_frame_host(), "document.body.innerHTML == ''")
.ExtractBool());
}
IN_PROC_BROWSER_TEST_P(SitePerProcessIsolatedSandboxedIframeTest,
SandboxedIframeWithDataURLIsIsolated) {
GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
std::string data_url_str("data:text/html,dataurl");
{
std::string js_str = base::StringPrintf(
"var frame = document.createElement('iframe'); "
"frame.id = 'test_frame'; "
"frame.sandbox = ''; "
"frame.src = '%s'; "
"document.body.appendChild(frame);",
data_url_str.c_str());
EXPECT_TRUE(ExecJs(shell(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
ASSERT_EQ(1U, root->child_count());
FrameTreeNode* child = root->child_at(0);
EXPECT_NE(root->current_frame_host()->GetSiteInstance(),
child->current_frame_host()->GetSiteInstance());
EXPECT_TRUE(child->current_frame_host()
->GetSiteInstance()
->GetSiteInfo()
.is_sandboxed());
EXPECT_FALSE(root->current_frame_host()
->GetSiteInstance()
->GetSiteInfo()
.is_sandboxed());
}
IN_PROC_BROWSER_TEST_P(SitePerProcessIsolatedSandboxedIframeTest,
SandboxedIframeWithDataURL) {
GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
std::string data_url_str("data:text/html,dataurl");
{
std::string js_str = base::StringPrintf(
"var frame = document.createElement('iframe'); "
"frame.id = 'test_frame'; "
"frame.src = '%s'; "
"document.body.appendChild(frame);",
data_url_str.c_str());
EXPECT_TRUE(ExecJs(shell(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
ASSERT_EQ(1U, root->child_count());
FrameTreeNode* child = root->child_at(0);
EXPECT_EQ(root->current_frame_host()->GetSiteInstance(),
child->current_frame_host()->GetSiteInstance());
{
std::string js_str(
"var frame = document.getElementById('test_frame'); "
"frame.sandbox = ''; ");
EXPECT_TRUE(ExecJs(shell(), js_str));
}
NavigateFrameToURL(child,
embedded_test_server()->GetURL("b.com", "/title1.html"));
EXPECT_NE(root->current_frame_host()->GetSiteInstance(),
child->current_frame_host()->GetSiteInstance());
EXPECT_TRUE(web_contents()->GetController().CanGoBack());
{
TestFrameNavigationObserver frame_observer(child);
web_contents()->GetController().GoBack();
frame_observer.WaitForCommit();
}
EXPECT_NE(root->current_frame_host()->GetSiteInstance(),
child->current_frame_host()->GetSiteInstance());
EXPECT_EQ(GURL(data_url_str),
child->current_frame_host()->GetLastCommittedURL());
}
IN_PROC_BROWSER_TEST_P(SitePerProcessIsolatedSandboxedIframeTest,
SandboxedParentWithSandboxedChildWithDataURL) {
GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
std::string parent_url_str = main_url.spec();
std::string data_url_str("data:text/html,dataurl");
EXPECT_TRUE(NavigateToURL(shell(), main_url));
{
std::string js_str = base::StringPrintf(
"var frame = document.createElement('iframe'); "
"frame.sandbox = 'allow-scripts'; "
"frame.src = '%s'; "
"document.body.appendChild(frame);",
parent_url_str.c_str());
EXPECT_TRUE(ExecJs(shell(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
ASSERT_EQ(1U, root->child_count());
FrameTreeNode* child = root->child_at(0);
EXPECT_NE(root->current_frame_host()->GetSiteInstance(),
child->current_frame_host()->GetSiteInstance());
{
std::string js_str = base::StringPrintf(
"var frame = document.createElement('iframe'); "
"frame.sandbox = 'allow-scripts'; "
"frame.src = '%s'; "
"document.body.appendChild(frame);",
data_url_str.c_str());
EXPECT_TRUE(ExecJs(child->current_frame_host(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
ASSERT_EQ(1U, child->child_count());
FrameTreeNode* grandchild = child->child_at(0);
EXPECT_EQ(child->current_frame_host()->GetSiteInstance(),
grandchild->current_frame_host()->GetSiteInstance());
EXPECT_EQ(GURL(data_url_str),
grandchild->current_frame_host()->GetLastCommittedURL());
}
IN_PROC_BROWSER_TEST_P(SitePerProcessIsolatedSandboxedIframeTest,
IsolatedSandboxWithNonSandboxedSubframe) {
GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
GURL child_url(
embedded_test_server()->GetURL("a.com", "/page_with_iframe.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
{
std::string js_str = base::StringPrintf(
"var frame = document.createElement('iframe'); "
"frame.sandbox = ''; "
"frame.src = '%s'; "
"document.body.appendChild(frame);",
child_url.spec().c_str());
EXPECT_TRUE(ExecJs(shell(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
ASSERT_EQ(1U, root->child_count());
FrameTreeNode* child = root->child_at(0);
EXPECT_EQ(network::mojom::WebSandboxFlags::kAll,
child->effective_frame_policy().sandbox_flags);
EXPECT_NE(root->current_frame_host()->GetSiteInstance(),
child->current_frame_host()->GetSiteInstance());
EXPECT_TRUE(child->current_frame_host()
->GetSiteInstance()
->GetSiteInfo()
.is_sandboxed());
ASSERT_EQ(1U, child->child_count());
FrameTreeNode* grand_child = child->child_at(0);
EXPECT_EQ(network::mojom::WebSandboxFlags::kAll,
grand_child->effective_frame_policy().sandbox_flags);
EXPECT_EQ(child->current_frame_host()->GetSiteInstance(),
grand_child->current_frame_host()->GetSiteInstance());
}
IN_PROC_BROWSER_TEST_P(
SitePerProcessIsolatedSandboxWithoutStrictSiteIsolationBrowserTest,
NotIsolatedSandbox) {
GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
GURL child_url(main_url);
EXPECT_TRUE(NavigateToURL(shell(), main_url));
{
std::string js_str = base::StringPrintf(
"var frame = document.createElement('iframe'); "
"frame.sandbox = ''; "
"frame.src = '%s'; "
"document.body.appendChild(frame);",
child_url.spec().c_str());
EXPECT_TRUE(ExecJs(shell(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
ASSERT_EQ(1U, root->child_count());
FrameTreeNode* child = root->child_at(0);
auto* parent_site_instance = root->current_frame_host()->GetSiteInstance();
auto* child_site_instance = child->current_frame_host()->GetSiteInstance();
EXPECT_EQ(network::mojom::WebSandboxFlags::kAll,
child->effective_frame_policy().sandbox_flags);
EXPECT_FALSE(parent_site_instance->RequiresDedicatedProcess());
EXPECT_EQ(parent_site_instance, child_site_instance);
EXPECT_FALSE(child_site_instance->GetSiteInfo().is_sandboxed());
}
IN_PROC_BROWSER_TEST_P(
SitePerProcessIsolatedSandboxWithoutStrictSiteIsolationBrowserTest,
IsolatedSandbox) {
GURL main_url(embedded_test_server()->GetURL("isolated.com", "/title1.html"));
GURL child_url(main_url);
EXPECT_TRUE(NavigateToURL(shell(), main_url));
{
std::string js_str = base::StringPrintf(
"var frame = document.createElement('iframe'); "
"frame.sandbox = ''; "
"frame.src = '%s'; "
"document.body.appendChild(frame);",
child_url.spec().c_str());
EXPECT_TRUE(ExecJs(shell(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
ASSERT_EQ(1U, root->child_count());
FrameTreeNode* child = root->child_at(0);
auto* parent_site_instance = root->current_frame_host()->GetSiteInstance();
auto* child_site_instance = child->current_frame_host()->GetSiteInstance();
EXPECT_EQ(network::mojom::WebSandboxFlags::kAll,
child->effective_frame_policy().sandbox_flags);
EXPECT_TRUE(parent_site_instance->RequiresDedicatedProcess());
EXPECT_NE(parent_site_instance, child_site_instance);
EXPECT_NE(parent_site_instance->GetProcess(),
child_site_instance->GetProcess());
EXPECT_TRUE(child_site_instance->GetSiteInfo().is_sandboxed());
}
IN_PROC_BROWSER_TEST_P(
SitePerProcessIsolatedSandboxWithoutStrictSiteIsolationBrowserTest,
CSPSandboxedMainFrame) {
GURL main_url(embedded_test_server()->GetURL(
"a.com", "/set-header?Content-Security-Policy: sandbox allow-scripts"));
GURL child_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
{
std::string js_str = base::StringPrintf(
"var frame = document.createElement('iframe'); "
"frame.sandbox = ''; "
"frame.src = '%s'; "
"document.body.appendChild(frame);",
child_url.spec().c_str());
EXPECT_TRUE(ExecJs(shell(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
ASSERT_EQ(1U, root->child_count());
FrameTreeNode* child = root->child_at(0);
auto* parent_site_instance = root->current_frame_host()->GetSiteInstance();
auto* child_site_instance = child->current_frame_host()->GetSiteInstance();
EXPECT_FALSE(parent_site_instance->RequiresDedicatedProcess());
EXPECT_FALSE(parent_site_instance->GetSiteInfo().is_sandboxed());
EXPECT_EQ(network::mojom::WebSandboxFlags::kNone,
root->effective_frame_policy().sandbox_flags);
EXPECT_EQ(parent_site_instance, child_site_instance);
}
IN_PROC_BROWSER_TEST_P(
SitePerProcessIsolatedSandboxWithoutStrictSiteIsolationBrowserTest,
CSPSandboxedMainframeIsolated) {
GURL main_url(embedded_test_server()->GetURL(
"isolated.com",
"/set-header?Content-Security-Policy: sandbox allow-scripts"));
GURL child_url(
embedded_test_server()->GetURL("isolated.com", "/title1.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
{
std::string js_str = base::StringPrintf(
"var frame = document.createElement('iframe'); "
"frame.sandbox = ''; "
"frame.src = '%s'; "
"document.body.appendChild(frame);",
child_url.spec().c_str());
EXPECT_TRUE(ExecJs(shell(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
ASSERT_EQ(1U, root->child_count());
FrameTreeNode* child = root->child_at(0);
auto* parent_site_instance = root->current_frame_host()->GetSiteInstance();
auto* child_site_instance = child->current_frame_host()->GetSiteInstance();
EXPECT_TRUE(parent_site_instance->RequiresDedicatedProcess());
EXPECT_TRUE(parent_site_instance->GetSiteInfo().is_sandboxed());
EXPECT_EQ(network::mojom::WebSandboxFlags::kNone,
root->effective_frame_policy().sandbox_flags);
EXPECT_EQ(parent_site_instance, child_site_instance);
}
IN_PROC_BROWSER_TEST_P(
SitePerProcessIsolatedSandboxWithoutStrictSiteIsolationBrowserTest,
MainFrameBrowsingInstanceSwap) {
GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
scoped_refptr<SiteInstanceImpl> site_instance_a =
web_contents()->GetSiteInstance();
EXPECT_FALSE(site_instance_a->GetSiteInfo().is_sandboxed());
GURL isolated_url(embedded_test_server()->GetURL(
"b.com", "/set-header?Content-Security-Policy: sandbox"));
SiteInstance::StartIsolatingSite(
shell()->web_contents()->GetController().GetBrowserContext(),
isolated_url,
content::ChildProcessSecurityPolicy::IsolatedOriginSource::TEST);
EXPECT_TRUE(NavigateToURL(shell(), isolated_url));
scoped_refptr<SiteInstanceImpl> site_instance_b =
web_contents()->GetSiteInstance();
EXPECT_NE(site_instance_a, site_instance_b);
EXPECT_NE(site_instance_a->GetIsolationContext().browsing_instance_id(),
site_instance_b->GetIsolationContext().browsing_instance_id());
EXPECT_FALSE(site_instance_b->GetSiteInfo().is_sandboxed());
}
IN_PROC_BROWSER_TEST_P(
SitePerProcessIsolatedSandboxWithoutStrictSiteIsolationBrowserTest,
MainFrameWithSandboxedOpener) {
GURL main_url(embedded_test_server()->GetURL("isolated.com", "/title1.html"));
GURL child_url(main_url);
EXPECT_TRUE(NavigateToURL(shell(), main_url));
{
std::string js_str = base::StringPrintf(
"var frame = document.createElement('iframe'); "
"frame.sandbox = 'allow-scripts allow-popups'; "
"frame.src = '%s'; "
"document.body.appendChild(frame);",
child_url.spec().c_str());
EXPECT_TRUE(ExecJs(shell(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
ASSERT_EQ(1U, root->child_count());
FrameTreeNode* child = root->child_at(0);
auto* parent_site_instance = root->current_frame_host()->GetSiteInstance();
auto* child_site_instance = child->current_frame_host()->GetSiteInstance();
network::mojom::WebSandboxFlags expected_flags =
network::mojom::WebSandboxFlags::kAll &
~network::mojom::WebSandboxFlags::kScripts &
~network::mojom::WebSandboxFlags::kPopups &
~network::mojom::WebSandboxFlags::kAutomaticFeatures &
~network::mojom::WebSandboxFlags::kTopNavigationToCustomProtocols;
EXPECT_EQ(expected_flags, child->effective_frame_policy().sandbox_flags);
EXPECT_TRUE(parent_site_instance->RequiresDedicatedProcess());
EXPECT_NE(parent_site_instance, child_site_instance);
EXPECT_TRUE(child_site_instance->GetSiteInfo().is_sandboxed());
Shell* new_shell = OpenPopup(child, child_url, "");
EXPECT_TRUE(new_shell);
FrameTreeNode* new_root =
static_cast<WebContentsImpl*>(new_shell->web_contents())
->GetPrimaryFrameTree()
.root();
auto* new_window_site_instance =
new_root->current_frame_host()->GetSiteInstance();
EXPECT_TRUE(new_window_site_instance->RequiresDedicatedProcess());
EXPECT_TRUE(new_window_site_instance->GetSiteInfo().is_sandboxed());
EXPECT_EQ(child_site_instance, new_window_site_instance);
}
IN_PROC_BROWSER_TEST_P(SitePerProcessPerDocumentIsolatedSandboxedIframeTest,
SameOriginIsolatedSandboxedIframes) {
GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
GURL same_origin_child_url(
embedded_test_server()->GetURL("sub.a.com", "/title1.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
{
std::string js_str = base::StringPrintf(
"var frame1 = document.createElement('iframe'); "
"frame1.sandbox = ''; "
"frame1.src = '%s'; "
"document.body.appendChild(frame1); "
"var frame2 = document.createElement('iframe'); "
"frame2.sandbox = ''; "
"frame2.src = '%s'; "
"document.body.appendChild(frame2);",
same_origin_child_url.spec().c_str(),
same_origin_child_url.spec().c_str());
EXPECT_TRUE(ExecJs(shell(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
ASSERT_EQ(2U, root->child_count());
FrameTreeNode* child1 = root->child_at(0);
EXPECT_EQ(network::mojom::WebSandboxFlags::kAll,
child1->effective_frame_policy().sandbox_flags);
EXPECT_NE(root->current_frame_host()->GetSiteInstance(),
child1->current_frame_host()->GetSiteInstance());
EXPECT_TRUE(child1->current_frame_host()
->GetSiteInstance()
->GetSiteInfo()
.is_sandboxed());
EXPECT_FALSE(root->current_frame_host()
->GetSiteInstance()
->GetSiteInfo()
.is_sandboxed());
FrameTreeNode* child2 = root->child_at(1);
EXPECT_EQ(network::mojom::WebSandboxFlags::kAll,
child2->effective_frame_policy().sandbox_flags);
EXPECT_NE(root->current_frame_host()->GetSiteInstance(),
child2->current_frame_host()->GetSiteInstance());
EXPECT_TRUE(child2->current_frame_host()
->GetSiteInstance()
->GetSiteInfo()
.is_sandboxed());
auto* child1_site_instance = child1->current_frame_host()->GetSiteInstance();
auto* child2_site_instance = child2->current_frame_host()->GetSiteInstance();
EXPECT_EQ(child1_site_instance->GetSiteInfo().site_url(),
child2_site_instance->GetSiteInfo().site_url());
EXPECT_NE(child1_site_instance->GetSiteInfo().unique_sandbox_id(),
child2_site_instance->GetSiteInfo().unique_sandbox_id());
EXPECT_NE(child1_site_instance, child2_site_instance);
EXPECT_NE(child1_site_instance->GetProcess(),
child2_site_instance->GetProcess());
}
IN_PROC_BROWSER_TEST_P(SitePerProcessIsolatedSandboxedIframeTest,
NestedSrcdocIframes) {
GURL main_url(embedded_test_server()->GetURL("a.com", "/title2.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
{
std::string js_str =
"var frame = document.createElement('iframe'); "
"frame.sandbox = 'allow-scripts'; "
"frame.srcdoc = 'foo'; "
"document.body.appendChild(frame);";
EXPECT_TRUE(ExecJs(shell(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
ASSERT_EQ(1U, root->child_count());
FrameTreeNode* child = root->child_at(0);
GURL parent_base_url = GetFrameBaseUrl(root->current_frame_host());
GURL child_base_url = GetFrameBaseUrl(child->current_frame_host());
EXPECT_EQ(parent_base_url, child_base_url);
EXPECT_EQ(parent_base_url,
child->current_frame_host()->GetInheritedBaseUrl());
GURL new_root_base_url("http://b.com/");
{
std::string js_str = base::StringPrintf(
"var base_element = document.createElement('base'); "
"base_element.href = '%s'; "
"document.head.appendChild(base_element);",
new_root_base_url.spec().c_str());
EXPECT_TRUE(ExecJs(shell(), js_str));
EXPECT_EQ(new_root_base_url, GetFrameBaseUrl(shell()));
}
{
std::string js_str =
"var frame = document.createElement('iframe'); "
"frame.sandbox = 'allow-scripts'; "
"frame.srcdoc = 'foo'; "
"document.body.appendChild(frame);";
EXPECT_TRUE(ExecJs(child->current_frame_host(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
ASSERT_EQ(1U, child->child_count());
FrameTreeNode* grandchild = child->child_at(0);
EXPECT_EQ(parent_base_url, GetFrameBaseUrl(child->current_frame_host()));
EXPECT_EQ(parent_base_url,
child->current_frame_host()->GetInheritedBaseUrl());
EXPECT_EQ(parent_base_url, GetFrameBaseUrl(grandchild->current_frame_host()));
EXPECT_EQ(parent_base_url,
grandchild->current_frame_host()->GetInheritedBaseUrl());
}
IN_PROC_BROWSER_TEST_P(SitePerProcessPerDocumentIsolatedSandboxedIframeTest,
NestedIsolatedSandboxedIframes) {
GURL main_url(embedded_test_server()->GetURL("a.com", "/title2.html"));
GURL same_origin_child_url(
embedded_test_server()->GetURL("a.com", "/title1.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
{
std::string js_str = base::StringPrintf(
"var frame = document.createElement('iframe'); "
"frame.sandbox = 'allow-scripts'; "
"frame.src = '%s'; "
"document.body.appendChild(frame);",
same_origin_child_url.spec().c_str());
EXPECT_TRUE(ExecJs(shell(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
ASSERT_EQ(1U, root->child_count());
FrameTreeNode* child = root->child_at(0);
{
std::string js_str = base::StringPrintf(
"var frame = document.createElement('iframe'); "
"frame.sandbox = ''; "
"frame.src = '%s'; "
"document.body.appendChild(frame);",
same_origin_child_url.spec().c_str());
EXPECT_TRUE(ExecJs(child->current_frame_host(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
ASSERT_EQ(1U, child->child_count());
FrameTreeNode* grandchild = child->child_at(0);
auto* child_site_instance = child->current_frame_host()->GetSiteInstance();
auto* grandchild_site_instance =
grandchild->current_frame_host()->GetSiteInstance();
EXPECT_NE(child_site_instance, grandchild_site_instance);
EXPECT_NE(child_site_instance->GetProcess(),
grandchild_site_instance->GetProcess());
EXPECT_NE(child_site_instance->GetSiteInfo().unique_sandbox_id(),
grandchild_site_instance->GetSiteInfo().unique_sandbox_id());
}
IN_PROC_BROWSER_TEST_P(SitePerProcessPerDocumentIsolatedSandboxedIframeTest,
SandboxedIframeNavigations) {
GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
GURL same_site_child_url(
embedded_test_server()->GetURL("a.com", "/title1.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
{
std::string js_str = base::StringPrintf(
"var frame = document.createElement('iframe'); "
"frame.id = 'test_frame'; "
"frame.sandbox = ''; "
"frame.src = '%s'; "
"document.body.appendChild(frame);",
same_site_child_url.spec().c_str());
EXPECT_TRUE(ExecJs(shell(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
ASSERT_EQ(1U, root->child_count());
FrameTreeNode* child = root->child_at(0);
scoped_refptr<SiteInstanceImpl> root_site_instance =
root->current_frame_host()->GetSiteInstance();
EXPECT_FALSE(root_site_instance->GetSiteInfo().is_sandboxed());
scoped_refptr<SiteInstanceImpl> child_site_instance1 =
child->current_frame_host()->GetSiteInstance();
EXPECT_EQ(network::mojom::WebSandboxFlags::kAll,
child->effective_frame_policy().sandbox_flags);
EXPECT_NE(root_site_instance, child_site_instance1);
EXPECT_TRUE(child_site_instance1->GetSiteInfo().is_sandboxed());
{
std::string js_str = base::StringPrintf(
"var frame = document.getElementById('test_frame'); "
"frame.src = '%s#foo';",
same_site_child_url.spec().c_str());
EXPECT_TRUE(ExecJs(shell(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
scoped_refptr<SiteInstanceImpl> child_site_instance1a =
child->current_frame_host()->GetSiteInstance();
EXPECT_EQ(child_site_instance1, child_site_instance1a);
GURL same_site_child_url2(
embedded_test_server()->GetURL("a.com", "/title2.html"));
ASSERT_TRUE(NavigateIframeToURL(shell()->web_contents(), "test_frame",
same_site_child_url2));
scoped_refptr<SiteInstanceImpl> child_site_instance2 =
child->current_frame_host()->GetSiteInstance();
EXPECT_NE(child_site_instance1, child_site_instance2);
EXPECT_NE(child_site_instance1->GetSiteInfo().unique_sandbox_id(),
child_site_instance2->GetSiteInfo().unique_sandbox_id());
GURL cross_site_child_url(
embedded_test_server()->GetURL("b.com", "/title1.html"));
ASSERT_TRUE(NavigateIframeToURL(shell()->web_contents(), "test_frame",
cross_site_child_url));
scoped_refptr<SiteInstanceImpl> child_site_instance3 =
child->current_frame_host()->GetSiteInstance();
EXPECT_NE(child_site_instance1, child_site_instance3);
EXPECT_NE(child_site_instance1->GetSiteInfo().unique_sandbox_id(),
child_site_instance3->GetSiteInfo().unique_sandbox_id());
}
IN_PROC_BROWSER_TEST_P(SitePerProcessPerDocumentIsolatedSandboxedIframeTest,
SandboxedAboutBlankSubframes) {
GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
GURL same_site_child_url(
embedded_test_server()->GetURL("a.com", "/title1.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
{
std::string js_str = base::StringPrintf(
"var frame = document.createElement('iframe'); "
"frame.id = 'test_frame'; "
"frame.sandbox = 'allow-scripts'; "
"frame.src = '%s'; "
"document.body.appendChild(frame);",
same_site_child_url.spec().c_str());
EXPECT_TRUE(ExecJs(shell(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
ASSERT_EQ(1U, root->child_count());
FrameTreeNode* child = root->child_at(0);
{
std::string js_str =
"var frame = document.createElement('iframe'); "
"frame.id = 'test_frame'; "
"frame.src = 'about:blank'; "
"document.body.appendChild(frame);";
EXPECT_TRUE(ExecJs(child->current_frame_host(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
ASSERT_EQ(1U, child->child_count());
FrameTreeNode* grandchild = child->child_at(0);
scoped_refptr<SiteInstanceImpl> child_site_instance =
child->current_frame_host()->GetSiteInstance();
scoped_refptr<SiteInstanceImpl> grandchild_site_instance1 =
grandchild->current_frame_host()->GetSiteInstance();
EXPECT_EQ(child_site_instance, grandchild_site_instance1);
GURL cross_document_child_url(
embedded_test_server()->GetURL("a.com", "/title2.html"));
ASSERT_TRUE(NavigateToURLFromRenderer(grandchild, cross_document_child_url));
scoped_refptr<SiteInstanceImpl> grandchild_site_instance2 =
grandchild->current_frame_host()->GetSiteInstance();
EXPECT_NE(child_site_instance, grandchild_site_instance2);
EXPECT_NE(child_site_instance->GetSiteInfo().unique_sandbox_id(),
grandchild_site_instance2->GetSiteInfo().unique_sandbox_id());
}
IN_PROC_BROWSER_TEST_P(SitePerProcessPerDocumentIsolatedSandboxedIframeTest,
SiblingSrcdocIframesGetDifferentProcesses) {
GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
{
std::string js_str =
"var frame1 = document.createElement('iframe'); "
"frame1.sandbox = ''; "
"frame1.srcdoc = 'srcdoc sandboxed subframe1'; "
"var frame2 = document.createElement('iframe'); "
"frame2.sandbox = ''; "
"frame2.srcdoc = 'srcdoc sandboxed subframe2'; "
"document.body.appendChild(frame1); "
"document.body.appendChild(frame2);";
EXPECT_TRUE(ExecJs(shell(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
ASSERT_EQ(2U, root->child_count());
FrameTreeNode* child1 = root->child_at(0);
FrameTreeNode* child2 = root->child_at(1);
auto* root_site_instance = root->current_frame_host()->GetSiteInstance();
auto* child1_site_instance = child1->current_frame_host()->GetSiteInstance();
auto* child2_site_instance = child2->current_frame_host()->GetSiteInstance();
EXPECT_FALSE(root_site_instance->GetSiteInfo().is_sandboxed());
EXPECT_EQ(network::mojom::WebSandboxFlags::kAll,
child1->effective_frame_policy().sandbox_flags);
EXPECT_TRUE(child1_site_instance->GetSiteInfo().is_sandboxed());
EXPECT_EQ(network::mojom::WebSandboxFlags::kAll,
child2->effective_frame_policy().sandbox_flags);
EXPECT_TRUE(child2_site_instance->GetSiteInfo().is_sandboxed());
EXPECT_NE(root_site_instance, child1_site_instance);
EXPECT_NE(root_site_instance, child2_site_instance);
EXPECT_NE(child1_site_instance, child2_site_instance);
EXPECT_NE(child1_site_instance->GetSiteInfo().unique_sandbox_id(),
child2_site_instance->GetSiteInfo().unique_sandbox_id());
EXPECT_NE(child1_site_instance->GetProcess(),
child2_site_instance->GetProcess());
}
IN_PROC_BROWSER_TEST_P(SrcdocIsolatedSandboxedIframeTest, SrcdocIframe) {
StartEmbeddedServer();
GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
{
std::string js_str =
"const frame = document.createElement('iframe'); "
"frame.id = 'test_frame'; "
"frame.srcdoc = 'srcdoc test content'; "
"document.body.append(frame);";
EXPECT_TRUE(ExecJs(shell(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
->GetPrimaryFrameTree()
.root();
ASSERT_EQ(1U, root->child_count());
FrameTreeNode* child = root->child_at(0);
EXPECT_EQ(GURL(url::kAboutSrcdocURL), child->current_url());
EXPECT_EQ("srcdoc test content", child->srcdoc_value());
if (SiteIsolationPolicy::AreIsolatedSandboxedIframesEnabled()) {
EXPECT_EQ(main_url, GetFrameBaseUrl(child->parent()));
}
if (blink::features::IsNewBaseUrlInheritanceBehaviorEnabled()) {
EXPECT_EQ(main_url, child->current_frame_host()->GetInheritedBaseUrl());
}
EXPECT_EQ(main_url, GetFrameBaseUrl(child->current_frame_host()));
{
std::string js_str =
"const frame = document.getElementById('test_frame'); "
"frame.removeAttribute('srcdoc');";
EXPECT_TRUE(ExecJs(shell(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
EXPECT_EQ(
false,
EvalJs(shell(),
"document.getElementById('test_frame').hasAttribute('srcdoc')"));
}
EXPECT_EQ(GURL(url::kAboutBlankURL), child->current_url());
EXPECT_EQ("", child->srcdoc_value());
EXPECT_EQ(main_url, GetFrameBaseUrl(child->current_frame_host()));
if (blink::features::IsNewBaseUrlInheritanceBehaviorEnabled()) {
EXPECT_EQ(main_url, child->current_frame_host()->GetInheritedBaseUrl());
}
{
std::string js_str =
"const frame = document.createElement('iframe'); "
"frame.id = 'test_frame2'; "
"frame.src = 'about:srcdoc'; "
"document.body.append(frame);";
EXPECT_TRUE(ExecJs(shell(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
ASSERT_EQ(2U, root->child_count());
FrameTreeNode* child2 = root->child_at(1);
EXPECT_EQ(GURL(url::kAboutSrcdocURL), child2->current_url());
EXPECT_EQ("", child2->srcdoc_value());
EXPECT_EQ(main_url, GetFrameBaseUrl(child->current_frame_host()));
EXPECT_EQ(main_url, GetFrameBaseUrl(child2->parent()));
EXPECT_EQ(main_url, GetFrameBaseUrl(child2->current_frame_host()));
if (blink::features::IsNewBaseUrlInheritanceBehaviorEnabled()) {
EXPECT_EQ(main_url, child2->current_frame_host()->GetInheritedBaseUrl());
}
{
std::string js_str =
"const frame = document.getElementById('test_frame2'); "
"frame.removeAttribute('src');";
EXPECT_TRUE(ExecJs(shell(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
EXPECT_EQ(
false,
EvalJs(shell(),
"document.getElementById('test_frame').hasAttribute('src')"));
}
EXPECT_EQ(GURL(url::kAboutBlankURL), child2->current_url());
EXPECT_EQ("", child2->srcdoc_value());
EXPECT_EQ(GURL("about:blank"), child->current_url());
if (blink::features::IsNewBaseUrlInheritanceBehaviorEnabled()) {
EXPECT_EQ(main_url, child->current_frame_host()->GetInheritedBaseUrl());
}
}
IN_PROC_BROWSER_TEST_P(SrcdocIsolatedSandboxedIframeTest, FrameChangesBaseUrl) {
StartEmbeddedServer();
GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
FrameTreeNode* root_ftn =
static_cast<WebContentsImpl*>(shell()->web_contents())
->GetPrimaryFrameTree()
.root();
EXPECT_EQ(main_url, GetFrameBaseUrl(root_ftn->current_frame_host()));
EXPECT_EQ(GURL(), root_ftn->current_frame_host()->GetInheritedBaseUrl());
{
std::string js_str =
"const base_element = document.createElement('base'); "
"base_element.id = 'base_element'; "
"base_element.href = 'http://foo.com'; "
"document.head.append(base_element);";
EXPECT_TRUE(ExecJs(shell(), js_str));
EXPECT_EQ(
true,
EvalJs(shell(),
"document.getElementById('base_element').hasAttribute('href')"));
}
GURL foo_url("http://foo.com");
EXPECT_EQ(foo_url, GetFrameBaseUrl(root_ftn->current_frame_host()));
EXPECT_EQ(GURL(), root_ftn->current_frame_host()->GetInheritedBaseUrl());
{
EXPECT_TRUE(ExecJs(shell(), "document.querySelector('base').remove();"));
EXPECT_EQ(true,
EvalJs(shell(),
"document.getElementById('base_element') == undefined"));
}
EXPECT_EQ(main_url, GetFrameBaseUrl(root_ftn->current_frame_host()));
EXPECT_EQ(GURL(), root_ftn->current_frame_host()->GetInheritedBaseUrl());
}
IN_PROC_BROWSER_TEST_P(SrcdocIsolatedSandboxedIframeTest,
SandboxedSrcdocIframeAddsRemovesBaseUrl) {
StartEmbeddedServer();
GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
{
std::string js_str =
"var frame = document.createElement('iframe'); "
"frame.sandbox = 'allow-scripts'; "
"frame.srcdoc = 'foo'; "
"document.body.appendChild(frame);";
EXPECT_TRUE(ExecJs(shell(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
->GetPrimaryFrameTree()
.root();
auto* child = root->child_at(0);
EXPECT_EQ(main_url, GetFrameBaseUrl(child->current_frame_host()));
EXPECT_EQ(main_url, GetFrameBaseUrl(root->current_frame_host()));
if (blink::features::IsNewBaseUrlInheritanceBehaviorEnabled()) {
EXPECT_EQ(main_url, child->current_frame_host()->GetInheritedBaseUrl());
}
GURL b_url("http://b.com/");
{
std::string js_str = base::StringPrintf(
"var base_element = document.createElement('base'); "
"base_element.href = '%s'; "
"document.head.appendChild(base_element);",
b_url.spec().c_str());
EXPECT_TRUE(ExecJs(child, js_str));
EXPECT_EQ(b_url, GetFrameBaseUrl(child->current_frame_host()));
}
EXPECT_EQ(main_url, GetFrameBaseUrl(root->current_frame_host()));
EXPECT_EQ(b_url, GetFrameBaseUrl(child->current_frame_host()));
if (blink::features::IsNewBaseUrlInheritanceBehaviorEnabled()) {
EXPECT_EQ(main_url, child->current_frame_host()->GetInheritedBaseUrl());
}
GURL c_url("http://c.com/");
{
std::string js_str = base::StringPrintf(
"var base_element = document.createElement('base'); "
"base_element.href = '%s'; "
"document.head.appendChild(base_element);",
c_url.spec().c_str());
EXPECT_TRUE(ExecJs(root, js_str));
EXPECT_EQ(c_url, GetFrameBaseUrl(root->current_frame_host()));
}
EXPECT_EQ(b_url, GetFrameBaseUrl(child->current_frame_host()));
EXPECT_EQ(c_url, GetFrameBaseUrl(root->current_frame_host()));
if (blink::features::IsNewBaseUrlInheritanceBehaviorEnabled()) {
EXPECT_EQ(main_url, child->current_frame_host()->GetInheritedBaseUrl());
}
{
EXPECT_TRUE(ExecJs(child, "document.querySelector('base').remove();"));
if (SiteIsolationPolicy::AreIsolatedSandboxedIframesEnabled()) {
EXPECT_EQ(main_url, GetFrameBaseUrl(child->current_frame_host()));
}
if (blink::features::IsNewBaseUrlInheritanceBehaviorEnabled()) {
EXPECT_EQ(main_url, GetFrameBaseUrl(child->current_frame_host()));
EXPECT_EQ(main_url, child->current_frame_host()->GetInheritedBaseUrl());
} else {
EXPECT_EQ(c_url, GetFrameBaseUrl(child->current_frame_host()));
}
}
EXPECT_EQ(c_url, GetFrameBaseUrl(root->current_frame_host()));
}
IN_PROC_BROWSER_TEST_P(SrcdocIsolatedSandboxedIframeTest,
SrcdocParentChangesBaseUrl) {
StartEmbeddedServer();
GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
->GetPrimaryFrameTree()
.root();
GURL b_url("http://b.com/");
{
std::string js_str = base::StringPrintf(
"var base_element = document.createElement('base'); "
"base_element.href = '%s'; "
"document.head.appendChild(base_element);",
b_url.spec().c_str());
EXPECT_TRUE(ExecJs(root, js_str));
EXPECT_EQ(b_url, GetFrameBaseUrl(root->current_frame_host()));
}
{
std::string js_str =
"var frame = document.createElement('iframe'); "
"frame.id = 'child-srcdoc'; "
"frame.sandbox = 'allow-scripts'; "
"frame.srcdoc = 'foo'; "
"document.body.appendChild(frame);";
EXPECT_TRUE(ExecJs(shell(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
auto* child = root->child_at(0);
EXPECT_EQ(b_url, GetFrameBaseUrl(child->current_frame_host()));
EXPECT_EQ(b_url, GetFrameBaseUrl(root->current_frame_host()));
if (blink::features::IsNewBaseUrlInheritanceBehaviorEnabled()) {
EXPECT_EQ(b_url, child->current_frame_host()->GetInheritedBaseUrl());
}
EXPECT_TRUE(ExecJs(root, "document.querySelector('base').remove();"));
EXPECT_EQ(main_url, GetFrameBaseUrl(root->current_frame_host()));
EXPECT_EQ(b_url, GetFrameBaseUrl(child->current_frame_host()));
if (blink::features::IsNewBaseUrlInheritanceBehaviorEnabled()) {
EXPECT_EQ(b_url, child->current_frame_host()->GetInheritedBaseUrl());
}
{
EXPECT_TRUE(ExecJs(child, "location.reload();"));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
if (blink::features::IsNewBaseUrlInheritanceBehaviorEnabled()) {
EXPECT_EQ(b_url, GetFrameBaseUrl(child->current_frame_host()));
EXPECT_EQ(b_url, child->current_frame_host()->GetInheritedBaseUrl());
} else {
EXPECT_EQ(main_url, GetFrameBaseUrl(child->current_frame_host()));
}
{
EXPECT_TRUE(ExecJs(shell(),
"var frame = document.getElementById('child-srcdoc'); "
"frame.srcdoc = frame.srcdoc;"));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
EXPECT_EQ(main_url, GetFrameBaseUrl(child->current_frame_host()));
if (blink::features::IsNewBaseUrlInheritanceBehaviorEnabled()) {
EXPECT_EQ(main_url, child->current_frame_host()->GetInheritedBaseUrl());
}
}
IN_PROC_BROWSER_TEST_P(SrcdocIsolatedSandboxedIframeTest,
InheritedBaseUrlClearedOnNavigation) {
StartEmbeddedServer();
GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
GURL child_url(embedded_test_server()->GetURL("a.com", "/title2.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
->GetPrimaryFrameTree()
.root();
{
std::string js_str =
"var frame = document.createElement('iframe'); "
"frame.id = 'child-srcdoc'; "
"frame.srcdoc = 'foo'; "
"document.body.appendChild(frame);";
EXPECT_TRUE(ExecJs(shell(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
auto* child = root->child_at(0);
EXPECT_EQ(main_url, GetFrameBaseUrl(child->current_frame_host()));
if (blink::features::IsNewBaseUrlInheritanceBehaviorEnabled()) {
EXPECT_EQ(main_url, child->current_frame_host()->GetInheritedBaseUrl());
}
{
EXPECT_TRUE(ExecJs(shell(),
"var frame = document.getElementById('child-srcdoc'); "
"frame.removeAttribute('srcdoc'); "));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
EXPECT_EQ(GURL("about:blank"),
child->current_frame_host()->GetLastCommittedURL());
EXPECT_EQ(main_url, GetFrameBaseUrl(child->current_frame_host()));
if (blink::features::IsNewBaseUrlInheritanceBehaviorEnabled()) {
EXPECT_EQ(main_url, child->current_frame_host()->GetInheritedBaseUrl());
}
{
std::string js_str = base::StringPrintf(
"var frame = document.getElementById('child-srcdoc'); "
"frame.src = '%s';",
child_url.spec().c_str());
EXPECT_TRUE(ExecJs(shell(), js_str));
ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
}
EXPECT_EQ(child_url, child->current_frame_host()->GetLastCommittedURL());
EXPECT_EQ(child_url, GetFrameBaseUrl(child->current_frame_host()));
EXPECT_EQ(GURL(), child->current_frame_host()->GetInheritedBaseUrl());
}
IN_PROC_BROWSER_TEST_P(BaseUrlInheritanceBehaviorEnterprisePolicyTest,
VerifyEnterprisePolicyDisables) {
EXPECT_FALSE(SiteIsolationPolicy::AreIsolatedSandboxedIframesEnabled());
EXPECT_FALSE(blink::features::IsNewBaseUrlInheritanceBehaviorEnabled());
StartEmbeddedServer();
GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
EXPECT_NE(GURL("about:blank"), GetFrameBaseUrl(shell()));
FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
->GetPrimaryFrameTree()
.root();
ShellAddedObserver new_shell_observer;
EXPECT_TRUE(ExecJs(root, "popup = window.open('about:blank');"));
Shell* popup = new_shell_observer.GetShell();
EXPECT_EQ(GURL("about:blank"), GetFrameBaseUrl(popup));
}
IN_PROC_BROWSER_TEST_P(SitePerProcessIsolatedSandboxedIframeTest,
VerifyBaseUrlPlumbing) {
GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
GURL child_url(main_url);
EXPECT_TRUE(NavigateToURL(shell(), main_url));
FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
FrameNavigationEntry* root_frame_entry =
root->current_frame_host()->last_committed_frame_entry();
ASSERT_TRUE(root_frame_entry);
EXPECT_FALSE(root_frame_entry->initiator_base_url().has_value());
{
std::string js_str =
"const frm = document.createElement('iframe'); "
"frm.srcdoc = 'foo'; "
"document.body.appendChild(frm); ";
EXPECT_TRUE(ExecJs(shell(), js_str));
}
ASSERT_TRUE(WaitForLoadStop(web_contents()));
ASSERT_EQ(1U, root->child_count());
FrameTreeNode* child = root->child_at(0);
EXPECT_EQ(main_url, child->current_frame_host()->GetInheritedBaseUrl());
FrameNavigationEntry* child_frame_entry =
child->current_frame_host()->last_committed_frame_entry();
ASSERT_TRUE(child_frame_entry);
ASSERT_TRUE(child_frame_entry->initiator_base_url().has_value());
EXPECT_EQ(main_url, child_frame_entry->initiator_base_url().value());
{
std::string js_str =
"const frm = document.createElement('iframe'); "
"frm.src = 'about:blank'; "
"document.body.appendChild(frm); ";
EXPECT_TRUE(ExecJs(shell(), js_str));
}
ASSERT_TRUE(WaitForLoadStop(web_contents()));
ASSERT_EQ(2U, root->child_count());
child = root->child_at(1);
EXPECT_EQ(main_url, child->current_frame_host()->GetInheritedBaseUrl());
child_frame_entry = child->current_frame_host()->last_committed_frame_entry();
ASSERT_TRUE(child_frame_entry);
ASSERT_TRUE(child_frame_entry->initiator_base_url().has_value());
EXPECT_EQ(main_url, child_frame_entry->initiator_base_url().value());
EXPECT_TRUE(ExecJs(shell(), "location = 'about:blank';"));
ASSERT_TRUE(WaitForLoadStop(web_contents()));
root_frame_entry = root->current_frame_host()->last_committed_frame_entry();
ASSERT_TRUE(root_frame_entry);
ASSERT_TRUE(root_frame_entry->initiator_base_url().has_value());
EXPECT_EQ(main_url, root_frame_entry->initiator_base_url().value());
EXPECT_TRUE(NavigateToURL(shell(), GURL("about:blank")));
root_frame_entry = root->current_frame_host()->last_committed_frame_entry();
ASSERT_TRUE(root_frame_entry);
EXPECT_FALSE(root_frame_entry->initiator_base_url().has_value());
EXPECT_EQ(GURL(), root->current_frame_host()->GetInheritedBaseUrl());
}
IN_PROC_BROWSER_TEST_F(BaseUrlInheritanceBehaviorIframeTest,
PopupsInheritBaseUrl) {
StartEmbeddedServer();
GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
->GetPrimaryFrameTree()
.root();
ShellAddedObserver new_shell_observer;
EXPECT_TRUE(ExecJs(root, "var w = window.open()"));
Shell* new_shell = new_shell_observer.GetShell();
WebContentsImpl* new_contents =
static_cast<WebContentsImpl*>(new_shell->web_contents());
EXPECT_TRUE(WaitForLoadStop(new_contents));
ASSERT_NE(new_contents, shell()->web_contents());
FrameTreeNode* new_root = new_contents->GetPrimaryFrameTree().root();
EXPECT_EQ(EvalJs(root, "document.baseURI").ExtractString(),
EvalJs(new_root, "document.baseURI").ExtractString());
}
IN_PROC_BROWSER_TEST_F(BaseUrlInheritanceBehaviorIframeTest,
AboutBlankInheritsBaseUrlFromSiblingInitiator) {
StartEmbeddedServer();
GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
->GetPrimaryFrameTree()
.root();
EXPECT_TRUE(ExecJs(root,
"var frm = document.createElement('iframe'); "
"frm.src = 'about:blank'; "
"frm.id = 'frm1'; "
"document.body.appendChild(frm);"));
ASSERT_EQ(1U, root->child_count());
FrameTreeNode* child1 = root->child_at(0);
EXPECT_TRUE(ExecJs(root,
"var frm = document.createElement('iframe'); "
"frm.id = 'frm2'; "
"document.body.appendChild(frm);"));
ASSERT_EQ(2U, root->child_count());
FrameTreeNode* child2 = root->child_at(1);
EXPECT_TRUE(ExecJs(child1,
"var base = document.createElement('base'); "
"base.href = 'https://example.com'; "
"document.head.appendChild(base); "
"window.top.window[1].location.href = 'about:blank';"));
EXPECT_EQ(GURL("https://example.com"),
GetFrameBaseUrl(child2->current_frame_host()));
}
INSTANTIATE_TEST_SUITE_P(All,
SitePerProcessIsolatedSandboxedIframeTest,
testing::ValuesIn(RenderDocumentFeatureLevelValues()));
INSTANTIATE_TEST_SUITE_P(All,
SitePerProcessNotIsolatedSandboxedIframeTest,
testing::ValuesIn(RenderDocumentFeatureLevelValues()));
INSTANTIATE_TEST_SUITE_P(All,
SitePerProcessPerOriginIsolatedSandboxedIframeTest,
testing::ValuesIn(RenderDocumentFeatureLevelValues()));
INSTANTIATE_TEST_SUITE_P(
All,
SitePerProcessIsolatedSandboxWithoutStrictSiteIsolationBrowserTest,
testing::ValuesIn(RenderDocumentFeatureLevelValues()));
INSTANTIATE_TEST_SUITE_P(All,
SitePerProcessPerDocumentIsolatedSandboxedIframeTest,
testing::ValuesIn(RenderDocumentFeatureLevelValues()));
INSTANTIATE_TEST_SUITE_P(All,
SrcdocIsolatedSandboxedIframeTest,
testing::Bool(),
[](const testing::TestParamInfo<bool>& info) {
return info.param ? "isolated" : "non_isolated";
});
INSTANTIATE_TEST_SUITE_P(All,
BaseUrlInheritanceBehaviorEnterprisePolicyTest,
testing::Bool(),
[](const testing::TestParamInfo<bool>& info) {
return info.param ? "isolated" : "non_isolated";
});
}