// Copyright 2022 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "content/browser/process_lock.h" #include "content/browser/renderer_host/navigation_entry_restore_context_impl.h" #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/page_state/page_state_serialization.h" #include "third_party/blink/public/common/switches.h" namespace content { // Test class for tests involving base url inheritance behavior. class BaseUrlInheritanceIframeTest : public ContentBrowserTest { … }; // class BaseUrlInheritanceIframeTest // A test to ensure that a baseURI exceeding chromium's maximum length for urls // is not inherited. IN_PROC_BROWSER_TEST_F(BaseUrlInheritanceIframeTest, InheritedBaseUrlIsLessThan2MB) { … } // A test to make sure that restoring a session history entry that was saved // with an about:blank subframe never results in an initiator_base_url of // an empty string. std::nullopt is expected instead of an empty GURL with // legacy base url behavior, or the non-empty initiator base url in the // new base url inheritance mode. This test runs in both modes. IN_PROC_BROWSER_TEST_F(BaseUrlInheritanceIframeTest, BaseURLFromSessionHistoryIsNulloptNotEmptyString) { … } // Test class to allow testing srcdoc functionality both with and without // `kIsolateSandboxedIframes` enabled. The tests verify the correct operation of // plumbing of both srcdoc attribute values, as well as the srcdoc frame's // parent's base url values, to the srcdoc's frame's renderer. class SrcdocIsolatedSandboxedIframeTest : public ContentBrowserTest, public ::testing::WithParamInterface<bool> { … }; // class SrcdocIsolatedSandboxedIframeTest // Test the scenario where a Site A mainframe contains a Site B subframe which // in turn has a sandboxed srcdoc frame. If A tries to directly navigate // the srcdoc to about:srcdoc, the navigation should be blocked. IN_PROC_BROWSER_TEST_P(SrcdocIsolatedSandboxedIframeTest, SrcdocNavigationForCrossOriginInitiatorIsBlocked) { … } // Out-of-process-sandboxed-iframe (OOPSIF) tests. // // Test classes for isolating sandboxed iframes and documents in a different // process from the rest of their site. // See https://crbug.com/510122. class SitePerProcessIsolatedSandboxedIframeTest : public SitePerProcessBrowserTest { … }; // A test class to test IsolatedSandboxedIframes with and without // kOriginKeyedProcessesByDefault enabled. class OriginKeyedProcessIsolatedSandboxedIframeTest : public SitePerProcessBrowserTestBase, public ::testing::WithParamInterface<bool> { … }; class SitePerProcessNotIsolatedSandboxedIframeTest : public SitePerProcessBrowserTest { … }; // A test class to allow testing isolated sandboxed iframes using the per-origin // process model. class SitePerProcessPerOriginIsolatedSandboxedIframeTest : public SitePerProcessBrowserTest { … }; class SitePerProcessIsolatedSandboxWithoutStrictSiteIsolationBrowserTest : public SitePerProcessIsolatedSandboxedIframeTest { … }; // A test class to allow testing isolated sandboxed iframes using the // per-document grouping model. class SitePerProcessPerDocumentIsolatedSandboxedIframeTest : public SitePerProcessBrowserTest { … }; // The following test should not crash. In this test the // kIsolateSandboxedIframes flag is forced off, so we don't need to verify // the process isolation details, as is done in // SitePerProcessIsolatedSandboxedIframeTest.SrcdocCspSandboxIsIsolated below. // https://crbug.com/1319430 IN_PROC_BROWSER_TEST_P(SitePerProcessNotIsolatedSandboxedIframeTest, SrcdocSandboxFlagsCheck) { … } // Test that a sandboxed data url is loaded correctly (i.e. doesn't crash) both // with and without kOriginKeyedProcessesByDefault enabled. IN_PROC_BROWSER_TEST_P(OriginKeyedProcessIsolatedSandboxedIframeTest, DataUrlLoadsWithoutCrashing) { … } // Test that a srcdoc iframe that receives its sandbox flags from the CSP // attribute also gets process isolation. This test starts the same as // SitePerProcessNotIsolatedSandboxedIframeTest.SrcdocSandboxFlagsCheck, but in // this test the kIsolateSandboxedIframes flag is on, so we also verify that // the process isolation has indeed occurred. IN_PROC_BROWSER_TEST_P(SitePerProcessIsolatedSandboxedIframeTest, SrcdocCspSandboxIsIsolated) { … } // A test to verify that an iframe that is sandboxed using the 'csp' attribute // instead of the 'sandbox' attribute gets process isolation when the // kIsolatedSandboxedIframes flag is enabled. IN_PROC_BROWSER_TEST_P(SitePerProcessIsolatedSandboxedIframeTest, CspIsolatedSandbox) { … } // A test to verify that an iframe with a fully-restrictive sandbox is rendered // in a separate process from its parent frame even if they have the same // origin. IN_PROC_BROWSER_TEST_P(SitePerProcessIsolatedSandboxedIframeTest, IsolatedSandbox) { … } // A test to verify that postMessages sent to/from sandboxed frames get // delivered properly. IN_PROC_BROWSER_TEST_P(SitePerProcessIsolatedSandboxedIframeTest, PostMessage) { … } // Test that a sandboxed srcdoc iframe loads properly when its parent's url is // different from its site_url. The child should get its own SiteInstance with a // site_url based on the full origin of the parent's original url. IN_PROC_BROWSER_TEST_P(SitePerProcessPerOriginIsolatedSandboxedIframeTest, SrcdocSandboxedFrameWithNonSiteParent) { … } namespace { GURL GetFrameBaseUrl(RenderFrameHostImpl* rfhi) { … } GURL GetFrameBaseUrl(Shell* shell) { … } } // namespace IN_PROC_BROWSER_TEST_P(SitePerProcessPerOriginIsolatedSandboxedIframeTest, SrcdocSandboxedFrameInsideAboutBlank) { … } // Similar to SrcdocSandboxedFrameWithNonSiteParent, but this time the srcdoc // is opened from b.foo.com which is loaded in the SiteInstance that was // created for a.foo.com, so the SiteInstance cannot be used to specify the // origin the srcdoc should use, namely b.foo.com. IN_PROC_BROWSER_TEST_P(SitePerProcessPerOriginIsolatedSandboxedIframeTest, SrcdocSandboxedFrameWithNonSiteParent2) { … } // Test that sandboxed iframes that are same-site with their parent but // cross-origin from each other are put in different processes from each other, // when the 'per-origin' isolation grouping is active for // kIsolateSandboxedIframes. (In 'per-site' isolation mode they would be in the // same process.) IN_PROC_BROWSER_TEST_P(SitePerProcessPerOriginIsolatedSandboxedIframeTest, CrossOriginIsolatedSandboxedIframes) { … } // Test that, while using 'per-origin' isolation grouping, navigating a // sandboxed iframe from 'a.foo.com' to 'b.foo.com' results in the sandbox using // two different SiteInstances. IN_PROC_BROWSER_TEST_P(SitePerProcessPerOriginIsolatedSandboxedIframeTest, CrossOriginNavigationSwitchesSiteInstances) { … } // Test that navigating cross-origin from a non-sandboxed iframe to a CSP // sandboxed iframe results in switching to a new SiteInstance in a different // process. IN_PROC_BROWSER_TEST_P(SitePerProcessPerOriginIsolatedSandboxedIframeTest, CrossOriginNavigationToCSPSwitchesSiteInstances) { … } // Check that two same-site sandboxed iframes in unrelated windows share the // same process due to subframe process reuse. IN_PROC_BROWSER_TEST_P(SitePerProcessIsolatedSandboxedIframeTest, SandboxProcessReuse) { … } // A test to verify that when an iframe has two sibling subframes, each with a // fully-restrictive sandbox, that each of the three gets its own process // even though they are all same-origin. // Note: using "sandbox = ''" in this and the following tests creates fully // restricted sandboxes, which will include the kOrigin case we are interested // in. IN_PROC_BROWSER_TEST_P(SitePerProcessIsolatedSandboxedIframeTest, IsolatedSandboxSiblingSubframes) { … } IN_PROC_BROWSER_TEST_P(SitePerProcessIsolatedSandboxedIframeTest, IsolatedSandboxSrcdocSubframe) { … } // A test to make sure that about:blank in a sandboxed iframe doesn't get // process isolation. If it did, it would be impossible for the parent to inject // any content, and it would be stuck as empty content. IN_PROC_BROWSER_TEST_P(SitePerProcessIsolatedSandboxedIframeTest, NotIsolatedSandboxAboutBlankSubframe) { … } // Test to make sure that javascript: urls don't execute in a sandboxed iframe. IN_PROC_BROWSER_TEST_P(SitePerProcessIsolatedSandboxedIframeTest, SandboxedIframeWithJSUrl) { … } // Test to make sure that an iframe with a data:url is process isolated. IN_PROC_BROWSER_TEST_P(SitePerProcessIsolatedSandboxedIframeTest, SandboxedIframeWithDataURLIsIsolated) { … } // Verify that a navigation from a sandboxed iframe, with an origin distinct // from its parent, to about:blank succeeds. IN_PROC_BROWSER_TEST_P(SitePerProcessIsolatedSandboxedIframeTest, SandboxedNavigationToAboutBlank) { … } // Verify that a navigation from a sandboxed iframe, with an origin distinct // from its parent, to about:blank succeeds. This is a variation on // SandboxedNavigationToAboutBlank in which the parent removes the sandbox flag // after B has loaded, and before it navigates to about:blank. IN_PROC_BROWSER_TEST_P(SitePerProcessIsolatedSandboxedIframeTest, SandboxedNavigationToAboutBlank_SandboxRevokedByParent) { … } // Test to make sure that an iframe with a data:url is appropriately sandboxed. IN_PROC_BROWSER_TEST_P(SitePerProcessIsolatedSandboxedIframeTest, SandboxedIframeWithDataURL) { … } // Test to make sure that a sandboxed child iframe with a data url and a // sandboxed parent end up in the same SiteInstance. IN_PROC_BROWSER_TEST_P(SitePerProcessIsolatedSandboxedIframeTest, SandboxedParentWithSandboxedChildWithDataURL) { … } // Test to make sure that a sandboxed iframe with a (not-explicitly) sandboxed // subframe ends up in the same SiteInstance/process as its subframe. IN_PROC_BROWSER_TEST_P(SitePerProcessIsolatedSandboxedIframeTest, IsolatedSandboxWithNonSandboxedSubframe) { … } // A test to verify that an iframe with a fully-restrictive sandbox is rendered // in the same process as its parent frame when the parent frame is in a // default SiteInstance. IN_PROC_BROWSER_TEST_P( SitePerProcessIsolatedSandboxWithoutStrictSiteIsolationBrowserTest, NotIsolatedSandbox) { … } // Similar to the NotIsolatedSandbox test, but using a site that requires a // dedicated process, and thus resulting in a separate process for the sandboxed // iframe. IN_PROC_BROWSER_TEST_P( SitePerProcessIsolatedSandboxWithoutStrictSiteIsolationBrowserTest, IsolatedSandbox) { … } // In this test, a main frame requests sandbox isolation for a site that would // not normally be given a dedicated process. This causes the sandbox isolation // request to fail. IN_PROC_BROWSER_TEST_P( SitePerProcessIsolatedSandboxWithoutStrictSiteIsolationBrowserTest, CSPSandboxedMainFrame) { … } // Same as CSPSandboxedMainframe, but this time the site is isolatable on its // own, so it gets the sandbox attribute via the CSP header. IN_PROC_BROWSER_TEST_P( SitePerProcessIsolatedSandboxWithoutStrictSiteIsolationBrowserTest, CSPSandboxedMainframeIsolated) { … } // Test to verify which IsolationContext is used when a BrowsingInstance swap is // performed during a navigation. // Note: this test does not work as hoped, see comment before the final // expectation of the test. IN_PROC_BROWSER_TEST_P( SitePerProcessIsolatedSandboxWithoutStrictSiteIsolationBrowserTest, MainFrameBrowsingInstanceSwap) { … } IN_PROC_BROWSER_TEST_P( SitePerProcessIsolatedSandboxWithoutStrictSiteIsolationBrowserTest, MainFrameWithSandboxedOpener) { … } // Test that sandboxed iframes that are same-site with their parent but // same-origin to each other are put in different processes from each other, // when the 'per-document' isolation grouping is active for // kIsolateSandboxedIframes. (In 'per-site' and 'per-origin' isolation groupings // they would be in the same process.) IN_PROC_BROWSER_TEST_P(SitePerProcessPerDocumentIsolatedSandboxedIframeTest, SameOriginIsolatedSandboxedIframes) { … } // This test ensures that nested srcdoc iframes get correct base urls. IN_PROC_BROWSER_TEST_P(SitePerProcessIsolatedSandboxedIframeTest, NestedSrcdocIframes) { … } // Test to verify that nested sandboxed iframes aren't put in the same // SiteInstance. IN_PROC_BROWSER_TEST_P(SitePerProcessPerDocumentIsolatedSandboxedIframeTest, NestedIsolatedSandboxedIframes) { … } // Verify same-document navigations in a sandboxed iframe stay in the same // SiteInstance, and that the unique_sandbox_id changes for any // non-same-document navigation. IN_PROC_BROWSER_TEST_P(SitePerProcessPerDocumentIsolatedSandboxedIframeTest, SandboxedIframeNavigations) { … } // Verify that a sandboxed iframe with an about:blank subframe shares its // SiteInstance with that subframe. Further, if the about:blank subframe // navigates cross-site, it gets a new SiteInstance. IN_PROC_BROWSER_TEST_P(SitePerProcessPerDocumentIsolatedSandboxedIframeTest, SandboxedAboutBlankSubframes) { … } // Test to verify that sibling srcdoc sandboxed iframes are placed in separate // SiteInstances in the per-document grouping model. IN_PROC_BROWSER_TEST_P(SitePerProcessPerDocumentIsolatedSandboxedIframeTest, SiblingSrcdocIframesGetDifferentProcesses) { … } // Test that changes to an iframe's srcdoc attribute propagate through the // browser and are stored/cleared on the RenderFrameHost as needed. IN_PROC_BROWSER_TEST_P(SrcdocIsolatedSandboxedIframeTest, SrcdocIframe) { … } // Test that when a frame changes its base url by manipulating its // base-element, and then undoes those changes, that the browser is properly // notified. IN_PROC_BROWSER_TEST_P(SrcdocIsolatedSandboxedIframeTest, FrameChangesBaseUrl) { … } // A test to make sure that a sandboxed srcdoc iframe correctly updates its // base url with the <base> element, and restores the snapshotted base url from // the parent if it removes its <base> element. IN_PROC_BROWSER_TEST_P(SrcdocIsolatedSandboxedIframeTest, SandboxedSrcdocIframeAddsRemovesBaseUrl) { … } // Test that when a sandboxed srcdoc iframe's parent changes its base url, the // srcdoc continues to use the original base url until it reloads. IN_PROC_BROWSER_TEST_P(SrcdocIsolatedSandboxedIframeTest, SrcdocParentChangesBaseUrl) { … } // A test to verify that the base url stored in RFHI for an about:srcdoc frame // is cleared when the frame navigates to a non-srcdoc/blank url. IN_PROC_BROWSER_TEST_P(SrcdocIsolatedSandboxedIframeTest, InheritedBaseUrlClearedOnNavigation) { … } // A test to verify the initial stages of the initiator base url plumbing work. // The test verifies the value propagates as far as NavigationRequest and // FrameNavigationEntry. IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, VerifyBaseUrlPlumbing) { … } // This test verifies that a renderer process doesn't crash if a srcdoc calls // document.write on a mainframe parent. IN_PROC_BROWSER_TEST_F(BaseUrlInheritanceIframeTest, SrcdocWritesMainFrame) { … } // A test to verify that a new about:blank mainframe inherits its base url // from its initiator. IN_PROC_BROWSER_TEST_F(BaseUrlInheritanceIframeTest, PopupsInheritBaseUrl) { … } IN_PROC_BROWSER_TEST_F(BaseUrlInheritanceIframeTest, AboutBlankInheritsBaseUrlFromSiblingInitiator) { … } INSTANTIATE_TEST_SUITE_P(…); INSTANTIATE_TEST_SUITE_P(…); INSTANTIATE_TEST_SUITE_P(…); INSTANTIATE_TEST_SUITE_P(…); INSTANTIATE_TEST_SUITE_P(…); INSTANTIATE_TEST_SUITE_P(…); INSTANTIATE_TEST_SUITE_P(…); } // namespace content