// Copyright 2017 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include <sstream> #include <tuple> #include <vector> #include "base/command_line.h" #include "base/functional/bind.h" #include "base/memory/raw_ptr.h" #include "base/memory/raw_ref.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/test/bind.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "build/build_config.h" #include "content/browser/bad_message.h" #include "content/browser/child_process_security_policy_impl.h" #include "content/browser/origin_agent_cluster_isolation_state.h" #include "content/browser/process_lock.h" #include "content/browser/renderer_host/navigation_request.h" #include "content/browser/renderer_host/navigator.h" #include "content/browser/renderer_host/render_process_host_impl.h" #include "content/browser/site_info.h" #include "content/browser/storage_partition_impl.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/common/content_navigation_policy.h" #include "content/common/features.h" #include "content/public/browser/browser_or_resource_context.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/site_isolation_policy.h" #include "content/public/browser/storage_partition_config.h" #include "content/public/browser/web_exposed_isolation_level.h" #include "content/public/common/content_client.h" #include "content/public/common/content_features.h" #include "content/public/common/content_switches.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_utils.h" #include "content/public/test/content_mock_cert_verifier.h" #include "content/public/test/navigation_handle_observer.h" #include "content/public/test/prerender_test_util.h" #include "content/public/test/test_frame_navigation_observer.h" #include "content/public/test/test_navigation_observer.h" #include "content/public/test/test_utils.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/did_commit_navigation_interceptor.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/receiver_set.h" #include "net/dns/mock_host_resolver.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_response.h" #include "services/network/public/cpp/features.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/common/storage_key/storage_key.h" #include "third_party/blink/public/common/tokens/tokens.h" #include "third_party/blink/public/mojom/dom_storage/dom_storage.mojom-test-utils.h" #include "url/gurl.h" namespace content { IsolatedOriginSource; // This is a base class for all tests in this class. It does not isolate any // origins and only provides common helper functions to the other test classes. class IsolatedOriginTestBase : public ContentBrowserTest { … }; class IsolatedOriginTest : public IsolatedOriginTestBase { … }; // Tests that verify the header can be used to opt-in to origin isolation. class OriginIsolationOptInHeaderTest : public IsolatedOriginTestBase { … }; // A set of tests that enable OriginAgentCluster by default. class OriginIsolationDefaultOACTest : public OriginIsolationOptInHeaderTest { … }; // A set of tests that enable process-isolated OriginAgentCluster-by-default. class OriginKeyedProcessByDefaultTest : public OriginIsolationOptInHeaderTest { … }; class OriginIsolationPrerenderOptInHeaderTest : public OriginIsolationOptInHeaderTest { … }; // class OriginIsolationPrerenderOptInHeaderTest // As in OriginIsolationOptInHeaderTest, but with same-process origin // isolation. class SameProcessOriginIsolationOptInHeaderTest : public OriginIsolationOptInHeaderTest { … }; // As in SameProcessOriginIsolationOptInHeaderTest, but command-line isolate // foo.com. class SameProcessOriginIsolationOptInHeaderWithIsolatedOriginTest : public SameProcessOriginIsolationOptInHeaderTest { … }; // Force WebSecurity off for tests. class SameProcessNoWebSecurityOriginIsolationOptInHeaderTest : public SameProcessOriginIsolationOptInHeaderTest { … }; // Used for a few tests that check non-HTTPS secure context behavior. class OriginIsolationOptInHttpServerHeaderTest : public IsolatedOriginTestBase { … }; // This class allows testing the interaction of OptIn isolation and command-line // isolation for origins. Tests using this class will isolate foo.com and // bar.com by default using command-line isolation, but any opt-in isolation // will override this. class OriginIsolationOptInHeaderCommandLineTest : public OriginIsolationOptInHeaderTest { … }; // This test verifies that opt-in isolation takes precedence over command-line // isolation. It loads an opt-in isolated base origin (which would have // otherwise been isolated via command-line isolation), and then loads a child // frame sub-origin which should-not be isolated (but would have been if the // base origin was command-line isolated). IN_PROC_BROWSER_TEST_F(OriginIsolationOptInHeaderCommandLineTest, OptInOverridesCommandLine) { … } // A test to verify that an origin with a trailing dot in the domain name // doesn't crash when it opts-out of origin isolation when // kOriginAgentClusterDefaultEnabled is enabled. IN_PROC_BROWSER_TEST_F(OriginIsolationOptInHeaderTest, TrailingDotDomainOptOutDoesNotCrash) { … } // A test to confirm that "a.com." is treated as a separate host (and hence // a separate origin) from "a.com". See example at // https://url.spec.whatwg.org/#concept-domain. IN_PROC_BROWSER_TEST_F(OriginIsolationOptInHeaderTest, TrailingDotDomainIsolatesSeparately1) { … } // A test similar to TrailingDotDomainIsolatesSeparately1, but this time the // "a.com" domain does not opt-in via a header, and does not get an origin- // keyed process. Thus, it ends up in a separate process from "a.com.". IN_PROC_BROWSER_TEST_F(OriginIsolationOptInHeaderTest, TrailingDotDomainIsolatesSeparately2) { … } // A test to confirm that if an Origin-Agent-Cluster header is encountered (but // not committed) as part of a redirect, that it does not opt-in to // OriginAgentCluster isolation. The setup in this test is subtle, since in // order for the call to NavigationRequest::OnRequestRedirected() to attempt to // create a new SiteInstance, we must load the same origin the redirect wants to // use, and load it without OriginAgentCluster isolation. Prior to the fix for // https://crbug.com/1329061 the redirect would result in opting the origin into // OriginAgentCluster isolation since no global walk is present to detect that // it has already been loaded without. IN_PROC_BROWSER_TEST_F(OriginIsolationOptInHeaderTest, RedirectSameSiteWithOACDoesntOptIn) { … } // Same as the preceding test, but the redirect is cross-site. IN_PROC_BROWSER_TEST_F(OriginIsolationOptInHeaderTest, RedirectCrossSiteWithOACDoesntOptIn) { … } // This tests that header-based opt-in causes the origin to end up in the // isolated origins list. IN_PROC_BROWSER_TEST_F(OriginIsolationOptInHeaderTest, Basic) { … } // A test to ensure that origins whose host has a trailing dot pass the // validation checks for explicit opt-ins and opt-outs. This is an // `OriginKeyedProcessByDefaultTest` test in order that the explicit opt-out // will be tracked. Note: failure for either part of this test will involve // crashing on a CHECK in // ChildProcessSecurityPolicyImpl::AddOriginIsolationStateForBrowsingInstance(): IN_PROC_BROWSER_TEST_F(OriginKeyedProcessByDefaultTest, HostWithTrailingDotAllowed) { … } // A simple test that, when OAC-by-default is enabled with process-isolation, an // origin that receives default OAC is put in an origin-keyed process. IN_PROC_BROWSER_TEST_F(OriginKeyedProcessByDefaultTest, DefaultIsOriginKeyedProcess) { … } // A test to make sure that a renderer-initiated navigation from a default- // isolated frame to about:blank doesn't crash on a ProcessLock mismatch. IN_PROC_BROWSER_TEST_F(OriginKeyedProcessByDefaultTest, RendererInitiatedNavigationToAboutBlankSucceeds) { … } // A test to make sure that a renderer-initiated navigation from a default- // isolated frame to about:blank doesn't crash on a ProcessLock mismatch. // This test is similar to RendererInitiatedNavigationToAboutBlankSucceeds // but with BFCache disabled. IN_PROC_BROWSER_TEST_F( OriginKeyedProcessByDefaultTest, RendererInitiatedNavigationToAboutBlankSucceeds_BFCacheDisabled) { … } // The same as for DefaultOptInIsIsolated, but testing on a subframe. IN_PROC_BROWSER_TEST_F(OriginKeyedProcessByDefaultTest, SubframeDefaultIsOriginKeyedProcess) { … } // The test ExplicitOptInRespected tests the speculative RFH created before // receiving the OAC headers. The delay must be set to zero so that the // speculative RFH is always created before receiving the header. class OriginKeyedProcessByDefaultTestWithoutSpeculativeRFHDelay : public OriginKeyedProcessByDefaultTest { … }; // Using origin-keyed processes by default faces a challenge for speculative // RenderFrameHosts, which are created before any OAC headers arrive. // Note: the origin is tracked even though the SiteInfo still says it is an // origin-keyed process by default. IN_PROC_BROWSER_TEST_F( OriginKeyedProcessByDefaultTestWithoutSpeculativeRFHDelay, ExplicitOptInRespected) { … } // Process-isolated OAC-by-default should not process isolate a navigation that // explicitly opts-out. This test is important, in part, for making sure all the // CanAccessDataForOrigin checks encountered during the navigation pass. IN_PROC_BROWSER_TEST_F(OriginKeyedProcessByDefaultTest, ExplicitOptOutRespected) { … } namespace { void TestDefaultIsolationForFrame( FrameTreeNode* ftn, const GURL& default_isolated_url, bool expect_origin_agent_cluster, bool expect_requires_origin_keyed_process, bool expect_default_requires_origin_keyed_process) { … } } // namespace // This test verifies that locking the definition of default isolation to // individual BrowsingInstances works correctly when the underlying feature // is changed dynamically. IN_PROC_BROWSER_TEST_F(OriginKeyedProcessByDefaultTest, DynamicEnterprisePolicyChange) { … } IN_PROC_BROWSER_TEST_F(OriginIsolationDefaultOACTest, Basic) { … } // These tests ensure that non-HTTPS secure contexts (see // https://w3c.github.io/webappsec-secure-contexts/#is-origin-trustworthy) are // able to use origin isolation. IN_PROC_BROWSER_TEST_F(OriginIsolationOptInHttpServerHeaderTest, Localhost) { … } IN_PROC_BROWSER_TEST_F(OriginIsolationOptInHttpServerHeaderTest, DotLocalhost) { … } IN_PROC_BROWSER_TEST_F(OriginIsolationOptInHttpServerHeaderTest, OneTwentySeven) { … } // Two tests for basic OAC operation w.r.t. prerendering FrameTrees. // Basic test to make sure an origin opting-in in a primary FrameTree // triggers registration of a non-opting-origin in an existing prerendering // Frametree. IN_PROC_BROWSER_TEST_F(OriginIsolationPrerenderOptInHeaderTest, SimplePrerenderSubOriginIsolationTest) { … } // Basic test to make sure an origin opting-in in a prerendering FrameTree // triggers registration of a non-opting-origin in an existing primary // Frametree. IN_PROC_BROWSER_TEST_F(OriginIsolationPrerenderOptInHeaderTest, SimplePrerenderSubOriginIsolationTest2) { … } // Further tests deep-dive into various scenarios for the isolation opt-ins. // In this test the sub-origin is isolated because the header requests it. It // will have a different site instance than the main frame. IN_PROC_BROWSER_TEST_F(OriginIsolationOptInHeaderTest, SimpleSubOriginIsolationTest) { … } // Check that two same-site Origin-Agent-Cluster subframes in unrelated windows // obey the subframe process reuse policy. IN_PROC_BROWSER_TEST_F(OriginIsolationOptInHeaderTest, OriginAgentClusterProcessReuse) { … } // In this test the sub-origin is isolated because the header requests it. It // will have the same site instance as the main frame, and it will be in the // same process. IN_PROC_BROWSER_TEST_F(SameProcessOriginIsolationOptInHeaderTest, SimpleSubOriginIsolationTest) { … } // This test is *nearly* the same as SameProcessOriginIsolationOptInHeaderTest. // SimpleSubOriginIsolationTest, but here we have command-line isolated foo.com // so it will be in a site instance with a non-empty ProcessLock. But the // same-process OAC isolated.foo.com will still be in the same SiteInstance, // and checks on the expected ProcessLock for isolated.foo.com should pass, // i.e. it should be the same as for the foo.com process. IN_PROC_BROWSER_TEST_F( SameProcessOriginIsolationOptInHeaderWithIsolatedOriginTest, SimpleSubOriginIsolationTest) { … } // Verify OAC is calculated using the base URL when using LoadDataWithBaseURL() // (analogous to Android WebView's loadDataWithBaseURL()) when the actual site // does not specify an Origin-Agent-Cluster value. IN_PROC_BROWSER_TEST_F(SameProcessOriginIsolationOptInHeaderTest, LoadDataWithBaseURLNoOAC) { … } // Verify OAC is calculated using the base URL when using LoadDataWithBaseURL() // (analogous to Android WebView's loadDataWithBaseURL()). Unlike the previous // test, the actual site specifies an Origin-Agent-Cluster value, which should // be ignored. IN_PROC_BROWSER_TEST_F(SameProcessOriginIsolationOptInHeaderTest, LoadDataWithBaseURLWithOAC) { … } // This test checks that same-process OriginAgentCluster won't crash and will // apply properly when used on a localhost URL. See https://crbug.com/1276155. IN_PROC_BROWSER_TEST_F(SameProcessOriginIsolationOptInHeaderTest, Localhost) { … } // This test verifies that --disable-web-security overrides same-process // OriginAgentCluster (i.e. disables it). IN_PROC_BROWSER_TEST_F(SameProcessNoWebSecurityOriginIsolationOptInHeaderTest, DisableWebSecurityDisablesOriginAgentCluster) { … } // In this test the sub-origin isn't isolated because no header is set. It will // have the same site instance as the main frame. IN_PROC_BROWSER_TEST_F(OriginIsolationOptInHeaderTest, SimpleSubOriginNonIsolationTest) { … } // This test verifies that renderer-initiated navigations to/from isolated // sub-origins works as expected. IN_PROC_BROWSER_TEST_F(OriginIsolationOptInHeaderTest, RendererInitiatedNavigations) { … } // Check that navigating a main frame from an non-isolated origin to an // isolated origin and vice versa swaps processes and uses a new SiteInstance, // both for renderer-initiated and browser-initiated navigations. // Note: this test is essentially identical to // IsolatedOriginTest.MainFrameNavigation. IN_PROC_BROWSER_TEST_F(OriginIsolationOptInHeaderTest, MainFrameNavigation) { … } // This test ensures that if an origin starts off being isolated in a // BrowsingInstance, it continues that way within the BrowsingInstance, even // if a new policy is received that removes the opt-in request. IN_PROC_BROWSER_TEST_F(OriginIsolationOptInHeaderTest, OriginIsolationStateRetainedForBrowsingInstance) { … } // This test ensures that if an origin starts off not being isolated in a // BrowsingInstance, it continues that way within the BrowsingInstance, even // if the header starts being sent. // Case #1 where the non-opted-in origin is currently in the frame tree. IN_PROC_BROWSER_TEST_F(OriginIsolationOptInHeaderTest, OriginNonIsolationStateRetainedForBrowsingInstance1) { … } // This test ensures that if an origin starts off not being isolated in a // BrowsingInstance, it continues that way within the BrowsingInstance, even // if the header starts being sent. // Case #2 where the non-opted-in origin is currently not in the frame tree. IN_PROC_BROWSER_TEST_F(OriginIsolationOptInHeaderTest, OriginNonIsolationStateRetainedForBrowsingInstance2) { … } // This test makes sure that a different tab in the same BrowsingInstance where // an origin originally did not opt-in respects that state even if the // server sends a different header. IN_PROC_BROWSER_TEST_F(OriginIsolationOptInHeaderTest, OriginNonIsolationStateRetainedForPopup) { … } // This test creates a no-opener popup that is origin-isolated, and has two // same-sub-origin iframes, one of which requests isolation and one that // doesn't. The non-isolated child commits first, so the second child shouldn't // get isolation, but more importantly we shouldn't crash on a NOTREACHED() in // RenderFrameHostManager that is verifying that the second child frame was // put in a compatible renderer process. // https://crbug.com/1099718 IN_PROC_BROWSER_TEST_F(OriginIsolationOptInHeaderTest, NoKillForBrowsingInstanceDifferencesInProcess) { … } // Same as NoKillForBrowsingInstanceDifferencesInProcess, except the starting // page has an isolated iframe that matches the origin that won't get isolation // in the popup's BrowsingInstance. Since this means that the first // BrowsingInstance will show sub.foo.com as isolated, then if // CanAccessDataForOrigin only checks the first BrowsingInstance it will get the // wrong result. IN_PROC_BROWSER_TEST_F(OriginIsolationOptInHeaderTest, NoKillForBrowsingInstanceDifferencesInProcess2) { … } // This test handles the case where the base origin is isolated, but a // sub-origin isn't. In this case we need to place the sub-origin in a site- // keyed SiteInstance with the same site URL as the origin-keyed SiteInstance // used for the isolated base origin. Note: only the isolated base origin will // have a port in this test, as the non-isolated sub-origin will have its port // value stripped. The test IsolatedBaseOriginNoPorts tests the case where // neither the isolated base origin nor the non-isolated sub-origin has a port // value. IN_PROC_BROWSER_TEST_F(OriginIsolationOptInHeaderTest, IsolatedBaseOrigin) { … } // This test is the same as OriginIsolationOptInHeaderTest // .IsolatedBaseOrigin except it uses port-free URLs. This is critical since we // can have two SiteInstances with the same SiteURL as long as one is // origin-keyed and the other isn't. Site URLs used to be used as map-keys but // with opt-in origin isolation we need to also consider the keying flag. // When the URLs all have non-default ports, we will never have duplicate // site URLs since the site-keyed one will have the port stripped. IN_PROC_BROWSER_TEST_F(OriginIsolationOptInHeaderTest, IsolatedBaseOriginNoPorts) { … } IN_PROC_BROWSER_TEST_F(OriginIsolationOptInHeaderTest, SeparateBrowserContextTest) { … } // This test creates a scenario where we have a frame that is on the initial // NavigationEntry, and then we created another frame with the same origin // that opts-in to isolation. The opt-in triggers a walk of the session history // and the frame tree ... the session history won't pick up the first frame, but // the frame-tree walk should. // TODO(crbug.com/40467594): Once every created frame is guaranteed to // have a FrameNavigationEntry and thus represented in the sesion history, we // probably can remove the frame-tree walk. IN_PROC_BROWSER_TEST_F(OriginIsolationOptInHeaderTest, FrameTreeTest) { … } // Similar to FrameTreeTest, but we stop the navigation that's not requesting // isolation at the pending commit state in tab2, then verify that the FrameTree // walk has correctly registered the origin as non-isolated in tab2, but // isolated in tab1. IN_PROC_BROWSER_TEST_F(OriginIsolationOptInHeaderTest, FrameTreeTestPendingCommit) { … } // Helper class to navigate a second tab to a specified URL that requests opt-in // origin isolation just before the first tab processes the next // DidCommitProvisionalLoad message. class InjectIsolationRequestingNavigation : public DidCommitNavigationInterceptor { … }; // TODO(crbug.com/40708791): flaky on Android builders since 2020-07-28. #if BUILDFLAG(IS_ANDROID) #define MAYBE_FrameTreeTestBeforeDidCommit … #else #define MAYBE_FrameTreeTestBeforeDidCommit … #endif // This test is similar to the one above, but exercises the pending navigation // when it's at a different stage, namely between the CommitNavigation and // DidCommitProvisionalLoad, rather than at WillProcessResponse. IN_PROC_BROWSER_TEST_F(OriginIsolationOptInHeaderTest, MAYBE_FrameTreeTestBeforeDidCommit) { … } class StrictOriginIsolationTest : public IsolatedOriginTestBase { … }; IN_PROC_BROWSER_TEST_F(StrictOriginIsolationTest, SubframesAreIsolated) { … } IN_PROC_BROWSER_TEST_F(StrictOriginIsolationTest, MainframesAreIsolated) { … } // Ensure that navigations across two URLs that resolve to the same effective // URL won't result in a renderer kill with strict origin isolation. See // https://crbug.com/961386. IN_PROC_BROWSER_TEST_F(StrictOriginIsolationTest, NavigateToURLsWithSameEffectiveURL) { … } // Check that navigating a main frame from an non-isolated origin to an // isolated origin and vice versa swaps processes and uses a new SiteInstance, // both for renderer-initiated and browser-initiated navigations. IN_PROC_BROWSER_TEST_F(IsolatedOriginTest, MainFrameNavigation) { … } // Check that opening a popup for an isolated origin puts it into a new process // and its own SiteInstance. IN_PROC_BROWSER_TEST_F(IsolatedOriginTest, Popup) { … } // Check that navigating a subframe to an isolated origin puts the subframe // into an OOPIF and its own SiteInstance. Also check that the isolated // frame's subframes also end up in correct SiteInstance. IN_PROC_BROWSER_TEST_F(IsolatedOriginTest, Subframe) { … } // Check that when an non-isolated origin foo.com embeds a subframe from an // isolated origin, which then navigates to a non-isolated origin bar.com, // bar.com goes back to the main frame's SiteInstance. See // https://crbug.com/711006. IN_PROC_BROWSER_TEST_F(IsolatedOriginTest, NoOOPIFWhenIsolatedOriginNavigatesToNonIsolatedOrigin) { … } // Check that a new isolated origin subframe will attempt to reuse an existing // process for that isolated origin, even across BrowsingInstances. Also check // that main frame navigations to an isolated origin keep using the default // process model and do not reuse existing processes. IN_PROC_BROWSER_TEST_F(IsolatedOriginTest, SubframeReusesExistingProcess) { … } // Check that when a cross-site, non-isolated-origin iframe opens a popup, // navigates it to an isolated origin, and then the popup navigates back to its // opener iframe's site, the popup and the opener iframe end up in the same // process and can script each other. See https://crbug.com/796912. IN_PROC_BROWSER_TEST_F(IsolatedOriginTest, PopupNavigatesToIsolatedOriginAndBack) { … } // Check that when a non-isolated-origin page opens a popup, navigates it // to an isolated origin, and then the popup navigates to a third non-isolated // origin and finally back to its opener's origin, the popup and the opener // iframe end up in the same process and can script each other: // // foo.com // | // window.open() // | // V // about:blank -> isolated.foo.com -> bar.com -> foo.com // // This is a variant of PopupNavigatesToIsolatedOriginAndBack where the popup // navigates to a third site before coming back to the opener's site. See // https://crbug.com/807184. IN_PROC_BROWSER_TEST_F(IsolatedOriginTest, PopupNavigatesToIsolatedOriginThenToAnotherSiteAndBack) { … } // Check that with an ABA hierarchy, where B is an isolated origin, the root // and grandchild frames end up in the same process and can script each other. // See https://crbug.com/796912. IN_PROC_BROWSER_TEST_F(IsolatedOriginTest, IsolatedOriginSubframeCreatesGrandchildInRootSite) { … } // Check that isolated origins can access cookies. This requires cookie checks // on the IO thread to be aware of isolated origins. IN_PROC_BROWSER_TEST_F(IsolatedOriginTest, Cookies) { … } // Check that isolated origins won't be placed into processes for other sites // when over the process limit. IN_PROC_BROWSER_TEST_F(IsolatedOriginTest, ProcessLimit) { … } // Verify that a navigation to an non-isolated origin does not reuse a process // from a pending navigation to an isolated origin. See // https://crbug.com/738634. IN_PROC_BROWSER_TEST_F(IsolatedOriginTest, ProcessReuseWithResponseStartedFromIsolatedOrigin) { … } // When a navigation uses a siteless SiteInstance, and a second navigation // commits an isolated origin which reuses the siteless SiteInstance's process // before the first navigation's response is received, ensure that the first // navigation can still finish properly and transfer to a new process, without // an origin lock mismatch. See https://crbug.com/773809. IN_PROC_BROWSER_TEST_F(IsolatedOriginTest, ProcessReuseWithLazilyAssignedSiteInstance) { … } // Same as ProcessReuseWithLazilyAssignedSiteInstance above, but here the // navigation with a siteless SiteInstance is for an isolated origin, and the // unrelated tab loads an unisolated URL which reuses the siteless // SiteInstance's process. Although the unisolated URL won't lock that process // to an origin (except when running with --site-per-process), it should still // mark it as used and cause the isolated origin to transfer when it receives a // response. See https://crbug.com/773809. IN_PROC_BROWSER_TEST_F(IsolatedOriginTest, ProcessReuseWithLazilyAssignedIsolatedSiteInstance) { … } // Verify that a navigation to an unisolated origin cannot reuse a process from // a pending navigation to an isolated origin. Similar to // ProcessReuseWithResponseStartedFromIsolatedOrigin, but here the non-isolated // URL is the first to reach OnResponseStarted, which should mark the process // as "used", so that the isolated origin can't reuse it. See // https://crbug.com/738634. IN_PROC_BROWSER_TEST_F(IsolatedOriginTest, ProcessReuseWithResponseStartedFromUnisolatedOrigin) { … } // Verify that when a process has a pending SiteProcessCountTracker entry for // an isolated origin, and a navigation to a non-isolated origin reuses that // process, future isolated origin subframe navigations do not reuse that // process. See https://crbug.com/780661. IN_PROC_BROWSER_TEST_F( IsolatedOriginTest, IsolatedSubframeDoesNotReuseUnsuitableProcessWithPendingSiteEntry) { … } // Similar to the test above, but for a ServiceWorker. When a process has a // pending SiteProcessCountTracker entry for an isolated origin, and a // navigation to a non-isolated origin reuses that process, a ServiceWorker // subsequently created for that isolated origin shouldn't reuse that process. // See https://crbug.com/780661 and https://crbug.com/780089. IN_PROC_BROWSER_TEST_F( IsolatedOriginTest, IsolatedServiceWorkerDoesNotReuseUnsuitableProcessWithPendingSiteEntry) { … } // Check that subdomains on an isolated origin (e.g., bar.isolated.foo.com) // also end up in the isolated origin's SiteInstance. IN_PROC_BROWSER_TEST_F(IsolatedOriginTest, IsolatedOriginWithSubdomain) { … } // This class allows intercepting the BindStorageArea and OpenLocalStorage // methods in order to test what happens when parameters are changed. class StoragePartitonInterceptor : public blink::mojom::DomStorageInterceptorForTesting, public RenderProcessHostObserver { … }; std::optional<blink::LocalFrameToken> StoragePartitonInterceptor::saved_first_local_frame_token_ = …; // Save the first LocalFrameToken seen and inject it into future calls. void CreateTestDomStorageBackendToSaveFirstFrame( RenderProcessHostImpl* rph, mojo::PendingReceiver<blink::mojom::DomStorage> receiver) { … } // Inject (or not if null) a StorageKey and LocalFrameToken. void CreateTestDomStorageBackendToInjectValues( std::optional<blink::StorageKey> storage_key_to_inject, std::optional<blink::LocalFrameToken> local_frame_token_to_inject, RenderProcessHostImpl* rph, mojo::PendingReceiver<blink::mojom::DomStorage> receiver) { … } // Verify that a renderer process cannot read sessionStorage of another origin. IN_PROC_BROWSER_TEST_F(IsolatedOriginTest, SessionStorage_WrongOrigin) { … } // Verify not fatal if the renderer reads sessionStorage from an empty // LocalFrameToken. IN_PROC_BROWSER_TEST_F(IsolatedOriginTest, SessionStorage_EmptyLocalFrameToken) { … } // Verify fatal error if the renderer reads sessionStorage from the wrong // LocalFrameToken. IN_PROC_BROWSER_TEST_F(IsolatedOriginTest, SessionStorage_WrongLocalFrameToken) { … } // Verify not fatal if the renderer reads localStorage from an empty // LocalFrameToken. IN_PROC_BROWSER_TEST_F(IsolatedOriginTest, LocalStorage_EmptyLocalFrameToken) { … } // Verify fatal error if the renderer reads localStorage from the wrong // LocalFrameToken. IN_PROC_BROWSER_TEST_F(IsolatedOriginTest, LocalStorage_WrongLocalFrameToken) { … } // Verify that an isolated renderer process cannot read localStorage of an // origin outside of its isolated site. IN_PROC_BROWSER_TEST_F( IsolatedOriginTest, LocalStorageOriginEnforcement_IsolatedAccessingNonIsolated) { … } #if BUILDFLAG(IS_ANDROID) #define MAYBE_LocalStorageOriginEnforcement_NonIsolatedAccessingIsolated … #else // TODO(lukasza): https://crbug.com/566091: Once remote NTP is capable of // embedding OOPIFs, start enforcing citadel-style checks on desktop // platforms. #define MAYBE_LocalStorageOriginEnforcement_NonIsolatedAccessingIsolated … #endif // Verify that a non-isolated renderer process cannot read localStorage of an // isolated origin. // // TODO(alexmos, lukasza): https://crbug.com/764958: Replicate this test for // the IO-thread case. IN_PROC_BROWSER_TEST_F( IsolatedOriginTest, MAYBE_LocalStorageOriginEnforcement_NonIsolatedAccessingIsolated) { … } // Verify that an IPC request for reading localStorage of an *opaque* origin // will be rejected. IN_PROC_BROWSER_TEST_F(IsolatedOriginTest, LocalStorageOriginEnforcement_OpaqueOrigin) { … } class IsolatedOriginFieldTrialTest : public IsolatedOriginTestBase { … }; IN_PROC_BROWSER_TEST_F(IsolatedOriginFieldTrialTest, Test) { … } class IsolatedOriginCommandLineAndFieldTrialTest : public IsolatedOriginFieldTrialTest { … }; // Verify that the lists of isolated origins specified via --isolate-origins // and via field trials are merged. See https://crbug.com/894535. IN_PROC_BROWSER_TEST_F(IsolatedOriginCommandLineAndFieldTrialTest, Test) { … } // This is a regression test for https://crbug.com/793350 - the long list of // origins to isolate used to be unnecessarily propagated to the renderer // process, trigerring a crash due to exceeding kZygoteMaxMessageLength. class IsolatedOriginLongListTest : public IsolatedOriginTestBase { … }; IN_PROC_BROWSER_TEST_F(IsolatedOriginLongListTest, Test) { … } // Check that navigating a subframe to an isolated origin error page puts the // subframe into an OOPIF and its own SiteInstance. Also check that the error // page in a subframe ends up in the correct SiteInstance. IN_PROC_BROWSER_TEST_F(IsolatedOriginTest, SubframeErrorPages) { … } namespace { bool HasDefaultSiteInstance(RenderFrameHost* rfh) { … } } // namespace // Verify process assignment behavior for the case where a site that does not // require isolation embeds a frame that does require isolation, which in turn // embeds another site that does not require isolation. // A (Does not require isolation) // +-> B (requires isolation) // +-> C (different site from A that does not require isolation.) // +-> A (same site as top-level which also does not require isolation.) IN_PROC_BROWSER_TEST_F(IsolatedOriginTest, AIsolatedCA) { … } IN_PROC_BROWSER_TEST_F(IsolatedOriginTest, NavigateToBlobURL) { … } // Test that same-site cross-origin navigations keep user activation even when // origin isolation is enabled. IN_PROC_BROWSER_TEST_F(IsolatedOriginTest, UserActivationSameSite) { … } // Ensure that --disable-site-isolation-trials disables origin isolation. class IsolatedOriginTrialOverrideTest : public IsolatedOriginFieldTrialTest { … }; IN_PROC_BROWSER_TEST_F(IsolatedOriginTrialOverrideTest, Test) { … } // Ensure that --disable-site-isolation-trials and/or // --disable-site-isolation-for-policy do not override the flag. class IsolatedOriginPolicyOverrideTest : public IsolatedOriginFieldTrialTest { … }; IN_PROC_BROWSER_TEST_F(IsolatedOriginPolicyOverrideTest, Test) { … } // Ensure that --disable-site-isolation-trials and/or // --disable-site-isolation-for-policy do not override the flag. class IsolatedOriginNoFlagOverrideTest : public IsolatedOriginTest { … }; IN_PROC_BROWSER_TEST_F(IsolatedOriginNoFlagOverrideTest, Test) { … } // Verify that main frame's origin isolation still keeps all same-origin frames // in the same process. When allocating processes for a(b(c),d(c)), we should // ensure that "c" frames are in the same process. // // This is a regression test for https://crbug.com/787576. IN_PROC_BROWSER_TEST_F(IsolatedOriginNoFlagOverrideTest, SameOriginSubframesProcessSharing) { … } // Helper class for testing dynamically-added isolated origins. Tests that use // this run without full --site-per-process, but with two isolated origins that // are configured at startup (isolated.foo.com and isolated.bar.com). class DynamicIsolatedOriginTest : public IsolatedOriginTest { … }; // Check that dynamically added isolated origins take effect for future // BrowsingInstances only. IN_PROC_BROWSER_TEST_F(DynamicIsolatedOriginTest, IsolationAppliesToFutureBrowsingInstances) { … } // Check that dynamically added isolated origins take effect for future // BrowsingInstances only, focusing on various main frame navigations. IN_PROC_BROWSER_TEST_F(DynamicIsolatedOriginTest, MainFrameNavigations) { … } // Check that dynamically added isolated origins do not prevent older processes // for the same origin from accessing cookies. IN_PROC_BROWSER_TEST_F(DynamicIsolatedOriginTest, OldProcessCanAccessCookies) { … } // Verify that when isolating sub.foo.com dynamically, foo.com and sub.foo.com // start to be treated as cross-site for process model decisions. IN_PROC_BROWSER_TEST_F(DynamicIsolatedOriginTest, IsolatedSubdomain) { … } // Check that when an isolated origin takes effect in BrowsingInstance 1, a new // BrowsingInstance 2, which reuses an old process from BrowsingInstance 1 for // its main frame, still applies the isolated origin to its subframe. This // demonstrates that isolated origins can't be scoped purely based on process // IDs. IN_PROC_BROWSER_TEST_F(DynamicIsolatedOriginTest, NewBrowsingInstanceInOldProcess) { … } // Verify that a process locked to foo.com is not reused for a navigation to // foo.com that does not require a dedicated process. See // https://crbug.com/950453. IN_PROC_BROWSER_TEST_F(DynamicIsolatedOriginTest, LockedProcessNotReusedForNonisolatedSameSiteNavigation) { … } // Checks that isolated origins can be added only for a specific profile, // and that they don't apply to other profiles. IN_PROC_BROWSER_TEST_F(DynamicIsolatedOriginTest, PerProfileIsolation) { … } // Check that a dynamically added isolated origin can take effect on the next // main frame navigation by forcing a BrowsingInstance swap, in the case that // there are no script references to the frame being navigated. IN_PROC_BROWSER_TEST_F(DynamicIsolatedOriginTest, ForceBrowsingInstanceSwap) { … } // Same as the test above, but using a renderer-initiated navigation. Check // that a dynamically added isolated origin can take effect on the next main // frame navigation by forcing a BrowsingInstance swap, in the case that there // are no script references to the frame being navigated. IN_PROC_BROWSER_TEST_F(DynamicIsolatedOriginTest, ForceBrowsingInstanceSwap_RendererInitiated) { … } IN_PROC_BROWSER_TEST_F(DynamicIsolatedOriginTest, DontForceBrowsingInstanceSwapWhenScriptReferencesExist) { … } // This test ensures that when a page becomes isolated in the middle of // creating and navigating a new window, the new window prevents a // BrowsingInstance swap. IN_PROC_BROWSER_TEST_F( DynamicIsolatedOriginTest, DontForceBrowsingInstanceSwapWithPendingNavigationInNewWindow) { … } class IsolatedOriginTestWithStrictSiteInstances : public IsolatedOriginTest { … }; IN_PROC_BROWSER_TEST_F(IsolatedOriginTestWithStrictSiteInstances, NonIsolatedFramesCanShareDefaultProcess) { … } // Creates a non-isolated main frame with an isolated child and non-isolated // grandchild. With strict site isolation disabled and // kProcessSharingWithStrictSiteInstances enabled, the main frame and the // grandchild should be in the same process even though they have different // SiteInstances. IN_PROC_BROWSER_TEST_F(IsolatedOriginTestWithStrictSiteInstances, IsolatedChildWithNonIsolatedGrandchild) { … } // Navigate a frame into and out of an isolated origin. This should not // confuse BrowsingInstance into holding onto a stale default_process_. IN_PROC_BROWSER_TEST_F(IsolatedOriginTestWithStrictSiteInstances, SubframeNavigatesOutofIsolationThenToIsolation) { … } // Ensure a popup and its opener can go in the same process, even though // they have different SiteInstances with kProcessSharingWithStrictSiteInstances // enabled. IN_PROC_BROWSER_TEST_F(IsolatedOriginTestWithStrictSiteInstances, NonIsolatedPopup) { … } class WildcardOriginIsolationTest : public IsolatedOriginTestBase { … }; IN_PROC_BROWSER_TEST_F(WildcardOriginIsolationTest, MainFrameNavigation) { … } IN_PROC_BROWSER_TEST_F(WildcardOriginIsolationTest, SubFrameNavigation) { … } // Helper class for testing site isolation triggered by // Cross-Origin-Opener-Policy headers. These tests disable strict site // isolation by default, so that we can check whether a site becomes isolated // due to COOP on both desktop and Android. class COOPIsolationTest : public IsolatedOriginTestBase { … }; // Check that a main frame navigation to a COOP site (with no subsequent user // gesture) triggers isolation for that site within the current // BrowsingInstance. IN_PROC_BROWSER_TEST_F(COOPIsolationTest, SameOrigin) { … } // Verify that the same-origin-allow-popups COOP header value triggers // isolation, and that this behaves sanely with window.open(). IN_PROC_BROWSER_TEST_F(COOPIsolationTest, SameOriginAllowPopups) { … } // Verify that the `noopener-allow-popups COOP header value triggers isolation, // and that this behaves sanely with window.open(). IN_PROC_BROWSER_TEST_F(COOPIsolationTest, NoopenerAllowPopups) { … } // Verify that COOP isolation applies at a site (and not origin) granularity. // // Isolating sites rather than origins may seem counterintuitive, considering // the COOP header value that triggers isolation is "same-origin". However, // process isolation granularity that we can infer from COOP is quite different // from what that actual COOP value controls. The COOP "same-origin" value // specifies when to sever opener relationships and create a new // BrowsingInstance; a COOP "same-origin" main frame document may only stay in // the same BrowsingInstance as other same-origin COOP documents. However, // this does not apply to iframes, and it's possible to have a // foo.bar.coop.com(baz.coop.com) hierarchy where the main frame has COOP // "same-origin" but both frames set document.domain to coop.com and // synchronously script each other (*). Hence, in this case, we must isolate // the coop.com site and place the two frames in the same process. This test // covers that precise scenario. // // (*) In the future, COOP may disallow document.domain, in which case we may // need to revisit this. See https://github.com/whatwg/html/issues/6177. IN_PROC_BROWSER_TEST_F(COOPIsolationTest, SiteGranularity) { … } // Verify that COOP isolation applies when both COOP and COEP headers are set // (i.e., for a cross-origin-isolated page). This results in a different COOP // header value (kSameOriginPlusCoep) which should still trigger isolation. IN_PROC_BROWSER_TEST_F(COOPIsolationTest, COOPAndCOEP) { … } // Check that when a site triggers both COOP isolation and OriginAgentCluster, // both mechanisms take effect. This test uses a URL with default ports so // that we can exercise the site URL being the same with both COOP and OAC. IN_PROC_BROWSER_TEST_F(COOPIsolationTest, COOPAndOriginAgentClusterNoPorts) { … } // Check that when a site triggers both COOP isolation and OriginAgentCluster, // both mechanisms take effect. Similar to the test above, but starts on a URL // where the origin doesn't match the site. IN_PROC_BROWSER_TEST_F(COOPIsolationTest, COOPAndOriginAgentClusterOnSubdomain) { … } // Verify that if strict site isolation is in place, COOP isolation does not // add redundant isolated origins to ChildProcessSecurityPolicy. IN_PROC_BROWSER_TEST_F(COOPIsolationTest, SiteAlreadyRequiresDedicatedProcess) { … } // Verify that seeing a user activation on a COOP document triggers isolation // of that document's site in future BrowsingInstances, but doesn't affect any // existing BrowsingInstances. IN_PROC_BROWSER_TEST_F(COOPIsolationTest, UserActivation) { … } // Similar to the test above, but verify that a user activation on a same-site // subframe also triggers isolation of a COOP site in the main frame for future // BrowsingInstances. IN_PROC_BROWSER_TEST_F(COOPIsolationTest, UserActivationInSubframe) { … } // Similar to the test above, but verify that a user activation on a // same-origin about:blank subframe triggers isolation of a COOP site in the // main frame for future BrowsingInstances. IN_PROC_BROWSER_TEST_F(COOPIsolationTest, UserActivationInAboutBlankSubframe) { … } // Ensure that navigating to http://localhost which has COOP+COEP headers, and // hence will attempt to trigger COOP isolation, will not crash. See // https://crbug.com/1276155. IN_PROC_BROWSER_TEST_F(COOPIsolationTest, Localhost) { … } // Helper class for testing site isolation triggered by different JIT policies // being applied. class JITIsolationTest : public IsolatedOriginTest, public ::testing::WithParamInterface<bool> { … }; IN_PROC_BROWSER_TEST_P(JITIsolationTest, MainFrameTest) { … } IN_PROC_BROWSER_TEST_P(JITIsolationTest, DefaultSiteTest) { … } INSTANTIATE_TEST_SUITE_P(…); INSTANTIATE_TEST_SUITE_P(…); IN_PROC_BROWSER_TEST_F(JITIsolationTest, SubFrameTest) { … } // Check that jitless subframes obey process reuse policies. IN_PROC_BROWSER_TEST_F(JITIsolationTest, SubFrameProcessReuse) { … } } // namespace content