diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-12 14:27:29 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-13 09:35:20 +0000 |
commit | c30a6232df03e1efbd9f3b226777b07e087a1122 (patch) | |
tree | e992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/weblayer/browser/site_isolation_browsertest.cc | |
parent | 7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff) | |
download | qtwebengine-chromium-85-based.tar.gz |
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/weblayer/browser/site_isolation_browsertest.cc')
-rw-r--r-- | chromium/weblayer/browser/site_isolation_browsertest.cc | 256 |
1 files changed, 256 insertions, 0 deletions
diff --git a/chromium/weblayer/browser/site_isolation_browsertest.cc b/chromium/weblayer/browser/site_isolation_browsertest.cc new file mode 100644 index 00000000000..d10c39f10fc --- /dev/null +++ b/chromium/weblayer/browser/site_isolation_browsertest.cc @@ -0,0 +1,256 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/base_switches.h" +#include "base/files/file_path.h" +#include "base/system/sys_info.h" +#include "build/build_config.h" +#include "components/prefs/pref_service.h" +#include "components/site_isolation/features.h" +#include "components/site_isolation/pref_names.h" +#include "components/user_prefs/user_prefs.h" +#include "content/public/browser/site_isolation_policy.h" +#include "content/public/common/content_client.h" +#include "content/public/test/browser_test_utils.h" +#include "content/public/test/test_navigation_observer.h" +#include "net/dns/mock_host_resolver.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "weblayer/browser/browser_context_impl.h" +#include "weblayer/browser/browser_impl.h" +#include "weblayer/browser/content_browser_client_impl.h" +#include "weblayer/browser/profile_impl.h" +#include "weblayer/browser/tab_impl.h" +#include "weblayer/shell/browser/shell.h" +#include "weblayer/test/weblayer_browser_test.h" +#include "weblayer/test/weblayer_browser_test_utils.h" + +namespace weblayer { +using testing::IsEmpty; +using testing::UnorderedElementsAre; + +class SiteIsolationBrowserTest : public WebLayerBrowserTest { + public: + SiteIsolationBrowserTest() { + feature_list_.InitWithFeaturesAndParameters( + {{site_isolation::features::kSitePerProcessOnlyForHighMemoryClients, + {{site_isolation::features:: + kSitePerProcessOnlyForHighMemoryClientsParamName, + "128"}}}, + {site_isolation::features::kSiteIsolationForPasswordSites, {}}}, + {}); + } + + std::vector<std::string> GetSavedIsolatedSites() { + PrefService* prefs = + user_prefs::UserPrefs::Get(GetProfile()->GetBrowserContext()); + auto* list = + prefs->GetList(site_isolation::prefs::kUserTriggeredIsolatedOrigins); + std::vector<std::string> sites; + for (const base::Value& value : list->GetList()) + sites.push_back(value.GetString()); + return sites; + } + + // WebLayerBrowserTest: + void SetUpOnMainThread() override { + original_client_ = content::SetBrowserClientForTesting(&browser_client_); + host_resolver()->AddRule("*", "127.0.0.1"); + embedded_test_server()->ServeFilesFromSourceDirectory("weblayer/test/data"); + ASSERT_TRUE(embedded_test_server()->Start()); + + ASSERT_FALSE( + content::SiteIsolationPolicy::UseDedicatedProcessesForAllSites()); + ASSERT_TRUE( + content::SiteIsolationPolicy::AreDynamicIsolatedOriginsEnabled()); + } + + void TearDownOnMainThread() override { + content::SetBrowserClientForTesting(original_client_); + } + + void SetUpCommandLine(base::CommandLine* command_line) override { + command_line->AppendSwitch("ignore-certificate-errors"); + + // This way the test always sees the same amount of physical memory + // (kLowMemoryDeviceThresholdMB = 512MB), regardless of how much memory is + // available in the testing environment. + base::CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kEnableLowEndDeviceMode); + EXPECT_EQ(512, base::SysInfo::AmountOfPhysicalMemoryMB()); + } + + content::WebContents* GetWebContents() { + return static_cast<TabImpl*>(shell()->tab())->web_contents(); + } + + private: + // A browser client which forces off strict site isolation, so the test can + // assume password isolation is enabled. + class SiteIsolationContentBrowserClient : public ContentBrowserClientImpl { + public: + SiteIsolationContentBrowserClient() : ContentBrowserClientImpl(nullptr) {} + + bool ShouldEnableStrictSiteIsolation() override { return false; } + }; + + SiteIsolationContentBrowserClient browser_client_; + content::ContentBrowserClient* original_client_ = nullptr; + base::test::ScopedFeatureList feature_list_; +}; + +IN_PROC_BROWSER_TEST_F(SiteIsolationBrowserTest, + SiteIsIsolatedAfterEnteringPassword) { + GURL url = embedded_test_server()->GetURL("sub.foo.com", + "/simple_password_form.html"); + NavigateAndWaitForCompletion(url, shell()); + content::WebContents* contents = GetWebContents(); + + // foo.com should not be isolated to start with. Verify that a cross-site + // iframe does not become an OOPIF. + EXPECT_FALSE( + contents->GetMainFrame()->GetSiteInstance()->RequiresDedicatedProcess()); + std::string kAppendIframe = R"( + var i = document.createElement('iframe'); + i.id = 'child'; + document.body.appendChild(i);)"; + EXPECT_TRUE(content::ExecJs(contents, kAppendIframe)); + GURL bar_url(embedded_test_server()->GetURL("bar.com", "/simple_page.html")); + EXPECT_TRUE(NavigateIframeToURL(contents, "child", bar_url)); + content::RenderFrameHost* child = ChildFrameAt(contents->GetMainFrame(), 0); + EXPECT_FALSE(child->IsCrossProcessSubframe()); + + // Fill a form and submit through a <input type="submit"> button. + content::TestNavigationObserver observer(contents); + std::string kFillAndSubmit = + "document.getElementById('username_field').value = 'temp';" + "document.getElementById('password_field').value = 'random';" + "document.getElementById('input_submit_button').click()"; + EXPECT_TRUE(content::ExecJs(contents, kFillAndSubmit)); + observer.Wait(); + + // Since there were no script references from other windows, we should've + // swapped BrowsingInstances and put the result of the form submission into a + // dedicated process, locked to foo.com. Check that a cross-site iframe now + // becomes an OOPIF. + EXPECT_TRUE( + contents->GetMainFrame()->GetSiteInstance()->RequiresDedicatedProcess()); + EXPECT_TRUE(ExecJs(contents, kAppendIframe)); + EXPECT_TRUE(NavigateIframeToURL(contents, "child", bar_url)); + child = ChildFrameAt(contents->GetMainFrame(), 0); + EXPECT_TRUE(child->IsCrossProcessSubframe()); +} + +// TODO(crbug.com/654704): Android does not support PRE_ tests. +#if !defined(OS_ANDROID) +IN_PROC_BROWSER_TEST_F(SiteIsolationBrowserTest, + PRE_IsolatedSitesPersistAcrossRestarts) { + // There shouldn't be any saved isolated origins to start with. + EXPECT_THAT(GetSavedIsolatedSites(), IsEmpty()); + + // Isolate saved.com and saved2.com persistently. + GURL saved_url = + embedded_test_server()->GetURL("saved.com", "/simple_page.html"); + content::SiteInstance::StartIsolatingSite(GetProfile()->GetBrowserContext(), + saved_url); + GURL saved2_url = + embedded_test_server()->GetURL("saved2.com", "/simple_page.html"); + content::SiteInstance::StartIsolatingSite(GetProfile()->GetBrowserContext(), + saved2_url); + + NavigateAndWaitForCompletion(saved_url, shell()); + EXPECT_TRUE(GetWebContents() + ->GetMainFrame() + ->GetSiteInstance() + ->RequiresDedicatedProcess()); + + // Check that saved.com and saved2.com were saved to disk. + EXPECT_THAT(GetSavedIsolatedSites(), + UnorderedElementsAre("http://saved.com", "http://saved2.com")); +} + +IN_PROC_BROWSER_TEST_F(SiteIsolationBrowserTest, + IsolatedSitesPersistAcrossRestarts) { + // Check that saved.com and saved2.com are still saved to disk. + EXPECT_THAT(GetSavedIsolatedSites(), + UnorderedElementsAre("http://saved.com", "http://saved2.com")); + + // Check that these sites utilize a dedicated process after restarting, but a + // non-isolated foo.com URL does not. + GURL saved_url = + embedded_test_server()->GetURL("saved.com", "/simple_page.html"); + GURL saved2_url = + embedded_test_server()->GetURL("saved2.com", "/simple_page2.html"); + GURL foo_url = + embedded_test_server()->GetURL("foo.com", "/simple_page3.html"); + NavigateAndWaitForCompletion(saved_url, shell()); + content::WebContents* contents = GetWebContents(); + EXPECT_TRUE( + contents->GetMainFrame()->GetSiteInstance()->RequiresDedicatedProcess()); + NavigateAndWaitForCompletion(saved2_url, shell()); + EXPECT_TRUE( + contents->GetMainFrame()->GetSiteInstance()->RequiresDedicatedProcess()); + NavigateAndWaitForCompletion(foo_url, shell()); + EXPECT_FALSE( + contents->GetMainFrame()->GetSiteInstance()->RequiresDedicatedProcess()); +} +#endif + +IN_PROC_BROWSER_TEST_F(SiteIsolationBrowserTest, IsolatedSiteIsSavedOnlyOnce) { + GURL saved_url = + embedded_test_server()->GetURL("saved.com", "/simple_page.html"); + content::SiteInstance::StartIsolatingSite(GetProfile()->GetBrowserContext(), + saved_url); + content::SiteInstance::StartIsolatingSite(GetProfile()->GetBrowserContext(), + saved_url); + content::SiteInstance::StartIsolatingSite(GetProfile()->GetBrowserContext(), + saved_url); + EXPECT_THAT(GetSavedIsolatedSites(), + UnorderedElementsAre("http://saved.com")); +} + +// Verify that serving a Clear-Site-Data header does not clear saved isolated +// sites. Saved isolated sites should only be cleared by user-initiated actions. +IN_PROC_BROWSER_TEST_F(SiteIsolationBrowserTest, + ClearSiteDataHeaderDoesNotClearSavedIsolatedSites) { + // Start an HTTPS server, as Clear-Site-Data is only available on HTTPS URLs. + net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS); + https_server.AddDefaultHandlers( + base::FilePath(FILE_PATH_LITERAL("weblayer/test/data"))); + ASSERT_TRUE(https_server.Start()); + + // Isolate saved.com and verify it's been saved to disk. + GURL saved_url = https_server.GetURL("saved.com", "/clear_site_data.html"); + content::SiteInstance::StartIsolatingSite(GetProfile()->GetBrowserContext(), + saved_url); + EXPECT_THAT(GetSavedIsolatedSites(), + UnorderedElementsAre("https://saved.com")); + + // Navigate to a URL that serves a Clear-Site-Data header for cache, cookies, + // and DOM storage. This is the most that a Clear-Site-Data header could + // clear, and this should not clear saved isolated sites. + NavigateAndWaitForCompletion(saved_url, shell()); + EXPECT_THAT(GetSavedIsolatedSites(), + UnorderedElementsAre("https://saved.com")); +} + +IN_PROC_BROWSER_TEST_F(SiteIsolationBrowserTest, + ExplicitClearBrowsingDataClearsSavedIsolatedSites) { + GURL saved_url = + embedded_test_server()->GetURL("saved.com", "/simple_page.html"); + content::SiteInstance::StartIsolatingSite(GetProfile()->GetBrowserContext(), + saved_url); + EXPECT_THAT(GetSavedIsolatedSites(), + UnorderedElementsAre("http://saved.com")); + + base::RunLoop run_loop; + base::Time now = base::Time::Now(); + GetProfile()->ClearBrowsingData({BrowsingDataType::COOKIES_AND_SITE_DATA}, + now - base::TimeDelta::FromDays(1), now, + run_loop.QuitClosure()); + run_loop.Run(); + + EXPECT_THAT(GetSavedIsolatedSites(), IsEmpty()); +} + +} // namespace weblayer |