diff --git a/browser/ephemeral_storage/ephemeral_storage_browsertest.cc b/browser/ephemeral_storage/ephemeral_storage_browsertest.cc index c40bd38b4a53..867fbd4d97c0 100644 --- a/browser/ephemeral_storage/ephemeral_storage_browsertest.cc +++ b/browser/ephemeral_storage/ephemeral_storage_browsertest.cc @@ -59,15 +59,29 @@ content::EvalJsResult GetStorageValueInFrame(RenderFrameHost* host, return content::EvalJs(host, script); } +content::EvalJsResult GetStorageInFrame(RenderFrameHost* host, + StorageType storage_type) { + std::string script = base::StringPrintf("%sStorage;", ToString(storage_type)); + return content::EvalJs(host, script); +} + +void AssertStorageEmptyInFrame(RenderFrameHost* frame) { + EXPECT_EQ(nullptr, GetStorageInFrame(frame, StorageType::Local)); + EXPECT_EQ(nullptr, GetStorageInFrame(frame, StorageType::Session)); +} + +void AssertStorageEmptyInSubframes(WebContents* web_contents) { + RenderFrameHost* main_frame = web_contents->GetMainFrame(); + AssertStorageEmptyInFrame(content::ChildFrameAt(main_frame, 0)); + AssertStorageEmptyInFrame(content::ChildFrameAt(main_frame, 1)); +} + } // namespace -class EphemeralStorageBrowserTest : public InProcessBrowserTest { +class EphemeralStorageBaseBrowserTest : public InProcessBrowserTest { public: - EphemeralStorageBrowserTest() - : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) { - scoped_feature_list_.InitAndEnableFeature( - blink::features::kBraveEphemeralStorage); - } + EphemeralStorageBaseBrowserTest() + : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {} void SetUpOnMainThread() override { InProcessBrowserTest::SetUpOnMainThread(); @@ -162,12 +176,18 @@ class EphemeralStorageBrowserTest : public InProcessBrowserTest { GURL c_site_ephemeral_storage_url_; private: - DISALLOW_COPY_AND_ASSIGN(EphemeralStorageBrowserTest); + DISALLOW_COPY_AND_ASSIGN(EphemeralStorageBaseBrowserTest); }; -IN_PROC_BROWSER_TEST_F(EphemeralStorageBrowserTest, StorageIsPartitioned) { - AllowAllCookies(); +class EphemeralStorageBrowserTest : public EphemeralStorageBaseBrowserTest { + public: + EphemeralStorageBrowserTest() { + scoped_feature_list_.InitAndEnableFeature( + blink::features::kBraveEphemeralStorage); + } +}; +IN_PROC_BROWSER_TEST_F(EphemeralStorageBrowserTest, StorageIsPartitioned) { WebContents* first_party_tab = LoadURLInNewTab(b_site_ephemeral_storage_url_); WebContents* site_a_tab1 = LoadURLInNewTab(a_site_ephemeral_storage_url_); WebContents* site_a_tab2 = LoadURLInNewTab(a_site_ephemeral_storage_url_); @@ -229,8 +249,6 @@ IN_PROC_BROWSER_TEST_F(EphemeralStorageBrowserTest, StorageIsPartitioned) { IN_PROC_BROWSER_TEST_F(EphemeralStorageBrowserTest, NavigatingClearsEphemeralStorage) { - AllowAllCookies(); - ui_test_utils::NavigateToURL(browser(), a_site_ephemeral_storage_url_); auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); @@ -261,8 +279,6 @@ IN_PROC_BROWSER_TEST_F(EphemeralStorageBrowserTest, IN_PROC_BROWSER_TEST_F(EphemeralStorageBrowserTest, ClosingTabClearsEphemeralStorage) { - AllowAllCookies(); - WebContents* site_a_tab = LoadURLInNewTab(a_site_ephemeral_storage_url_); EXPECT_EQ(browser()->tab_strip_model()->count(), 2); @@ -303,8 +319,6 @@ IN_PROC_BROWSER_TEST_F(EphemeralStorageBrowserTest, IN_PROC_BROWSER_TEST_F(EphemeralStorageBrowserTest, ReloadDoesNotClearEphemeralStorage) { - AllowAllCookies(); - ui_test_utils::NavigateToURL(browser(), a_site_ephemeral_storage_url_); auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); @@ -334,8 +348,6 @@ IN_PROC_BROWSER_TEST_F(EphemeralStorageBrowserTest, IN_PROC_BROWSER_TEST_F(EphemeralStorageBrowserTest, EphemeralStorageDoesNotLeakBetweenProfiles) { - AllowAllCookies(); - ui_test_utils::NavigateToURL(browser(), a_site_ephemeral_storage_url_); auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); @@ -384,3 +396,106 @@ IN_PROC_BROWSER_TEST_F(EphemeralStorageBrowserTest, EXPECT_EQ(nullptr, private_values.iframe_1.session_storage); EXPECT_EQ(nullptr, private_values.iframe_2.session_storage); } + +IN_PROC_BROWSER_TEST_F(EphemeralStorageBrowserTest, ThirdPartyCookiesEnabled) { + AllowAllCookies(); + + ui_test_utils::NavigateToURL(browser(), b_site_ephemeral_storage_url_); + auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); + // We set a value in the page where all the frames are first-party. + SetValuesInFrames(web_contents, "b.com - first party", "from=b.com"); + + // The storage in the first-party iframes should still reflect the + // original value that was written in the non-ephemeral storage area. + ValuesFromFrames first_party_values = GetValuesFromFrames(web_contents); + EXPECT_EQ("b.com - first party", first_party_values.main_frame.local_storage); + EXPECT_EQ("b.com - first party", first_party_values.iframe_1.local_storage); + EXPECT_EQ("b.com - first party", first_party_values.iframe_2.local_storage); + + EXPECT_EQ("b.com - first party", + first_party_values.main_frame.session_storage); + EXPECT_EQ("b.com - first party", first_party_values.iframe_1.session_storage); + EXPECT_EQ("b.com - first party", first_party_values.iframe_2.session_storage); + + ui_test_utils::NavigateToURL(browser(), a_site_ephemeral_storage_url_); + auto* a_site_content = browser()->tab_strip_model()->GetActiveWebContents(); + + // If third-party cookies is enabled, site_a_tab should be able to access to + // non-ephemeral sotrages. + ValuesFromFrames site_a_tab_values = GetValuesFromFrames(a_site_content); + EXPECT_EQ(nullptr, site_a_tab_values.main_frame.local_storage); + EXPECT_EQ("b.com - first party", site_a_tab_values.iframe_1.local_storage); + EXPECT_EQ("b.com - first party", site_a_tab_values.iframe_2.local_storage); + + EXPECT_EQ(nullptr, site_a_tab_values.main_frame.session_storage); + EXPECT_EQ("b.com - first party", site_a_tab_values.iframe_1.session_storage); + EXPECT_EQ("b.com - first party", site_a_tab_values.iframe_2.session_storage); +} + +class EphemeralStorageDisabledBrowserTest + : public EphemeralStorageBaseBrowserTest { + public: + EphemeralStorageDisabledBrowserTest() { + scoped_feature_list_.InitAndDisableFeature( + blink::features::kBraveEphemeralStorage); + } +}; + +IN_PROC_BROWSER_TEST_F(EphemeralStorageDisabledBrowserTest, + ThirdPartyCookiesEnabled) { + AllowAllCookies(); + + ui_test_utils::NavigateToURL(browser(), b_site_ephemeral_storage_url_); + auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); + // We set a value in the page where all the frames are first-party. + SetValuesInFrames(web_contents, "b.com - first party", "from=b.com"); + + ValuesFromFrames first_party_values = GetValuesFromFrames(web_contents); + EXPECT_EQ("b.com - first party", first_party_values.main_frame.local_storage); + EXPECT_EQ("b.com - first party", first_party_values.iframe_1.local_storage); + EXPECT_EQ("b.com - first party", first_party_values.iframe_2.local_storage); + + EXPECT_EQ("b.com - first party", + first_party_values.main_frame.session_storage); + EXPECT_EQ("b.com - first party", first_party_values.iframe_1.session_storage); + EXPECT_EQ("b.com - first party", first_party_values.iframe_2.session_storage); + + ui_test_utils::NavigateToURL(browser(), a_site_ephemeral_storage_url_); + auto* a_site_content = browser()->tab_strip_model()->GetActiveWebContents(); + + // If third-party cookies is enabled, site_a_tab should be able to access to + // non-ephemeral sotrages. + ValuesFromFrames site_a_tab_values = GetValuesFromFrames(a_site_content); + EXPECT_EQ(nullptr, site_a_tab_values.main_frame.local_storage); + EXPECT_EQ("b.com - first party", site_a_tab_values.iframe_1.local_storage); + EXPECT_EQ("b.com - first party", site_a_tab_values.iframe_2.local_storage); + + EXPECT_EQ(nullptr, site_a_tab_values.main_frame.session_storage); + EXPECT_EQ("b.com - first party", site_a_tab_values.iframe_1.session_storage); + EXPECT_EQ("b.com - first party", site_a_tab_values.iframe_2.session_storage); +} + +IN_PROC_BROWSER_TEST_F(EphemeralStorageDisabledBrowserTest, + ThirdPartyCookiesDisabled) { + ui_test_utils::NavigateToURL(browser(), b_site_ephemeral_storage_url_); + auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); + // We set a value in the page where all the frames are first-party. + SetValuesInFrames(web_contents, "b.com - first party", "from=b.com"); + + ValuesFromFrames first_party_values = GetValuesFromFrames(web_contents); + EXPECT_EQ("b.com - first party", first_party_values.main_frame.local_storage); + EXPECT_EQ("b.com - first party", first_party_values.iframe_1.local_storage); + EXPECT_EQ("b.com - first party", first_party_values.iframe_2.local_storage); + + EXPECT_EQ("b.com - first party", + first_party_values.main_frame.session_storage); + EXPECT_EQ("b.com - first party", first_party_values.iframe_1.session_storage); + EXPECT_EQ("b.com - first party", first_party_values.iframe_2.session_storage); + + ui_test_utils::NavigateToURL(browser(), a_site_ephemeral_storage_url_); + auto* a_site_content = browser()->tab_strip_model()->GetActiveWebContents(); + + // If both ephemeral storage and third-party cookies disabled, third-party + // frames can not access to any dom storage. + AssertStorageEmptyInSubframes(a_site_content); +} diff --git a/chromium_src/third_party/blink/renderer/modules/storage/dom_window_storage.cc b/chromium_src/third_party/blink/renderer/modules/storage/dom_window_storage.cc index a45aed40b3aa..94be7731c126 100644 --- a/chromium_src/third_party/blink/renderer/modules/storage/dom_window_storage.cc +++ b/chromium_src/third_party/blink/renderer/modules/storage/dom_window_storage.cc @@ -170,17 +170,15 @@ StorageArea* BraveDOMWindowStorage::sessionStorage( DOMWindowStorage::From(*window).sessionStorage(exception_state); MaybeClearAccessDeniedException(storage, *window, &exception_state); - if (!base::FeatureList::IsEnabled(features::kBraveEphemeralStorage)) - return storage; - - if (!window->IsCrossSiteSubframe()) - return storage; - // If we were not able to create non-ephemeral session storage for this // window, then don't attempt to create an ephemeral version. if (!storage) return nullptr; + if (StorageController::CanAccessStorageAreaWithoutEphemeral( + window->GetFrame(), StorageArea::StorageType::kSessionStorage)) + return storage; + return ephemeralSessionStorage(); } @@ -210,17 +208,15 @@ StorageArea* BraveDOMWindowStorage::localStorage( auto* storage = DOMWindowStorage::From(*window).localStorage(exception_state); MaybeClearAccessDeniedException(storage, *window, &exception_state); - if (!base::FeatureList::IsEnabled(features::kBraveEphemeralStorage)) - return storage; - - if (!window->IsCrossSiteSubframe()) - return storage; - // If we were not able to create non-ephemeral localStorage for this Window, // then don't attempt to create an ephemeral version. if (!storage) return nullptr; + if (StorageController::CanAccessStorageAreaWithoutEphemeral( + window->GetFrame(), StorageArea::StorageType::kSessionStorage)) + return storage; + return ephemeralLocalStorage(); } diff --git a/chromium_src/third_party/blink/renderer/modules/storage/storage_controller.cc b/chromium_src/third_party/blink/renderer/modules/storage/storage_controller.cc new file mode 100644 index 000000000000..1e802be915e1 --- /dev/null +++ b/chromium_src/third_party/blink/renderer/modules/storage/storage_controller.cc @@ -0,0 +1,29 @@ +/* Copyright (c) 2020 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "third_party/blink/renderer/modules/storage/storage_controller.h" + +#include "third_party/blink/public/common/features.h" +#include "third_party/blink/renderer/core/frame/local_dom_window.h" +#include "third_party/blink/renderer/core/frame/local_frame.h" + +namespace blink { + +// static +bool StorageController::CanAccessStorageArea(LocalFrame* frame, + StorageArea::StorageType type) { + if (CanAccessStorageAreaWithoutEphemeral(frame, type)) + return true; + if (frame && frame->GetDocument() && frame->GetDocument()->domWindow() && + frame->GetDocument()->domWindow()->IsCrossSiteSubframe()) + return base::FeatureList::IsEnabled(features::kBraveEphemeralStorage); + return false; +} + +} // namespace blink + +#define CanAccessStorageArea CanAccessStorageAreaWithoutEphemeral +#include "../../../../../../../third_party/blink/renderer/modules/storage/storage_controller.cc" +#undef CanAccessStorageAreaWithoutEphemeral diff --git a/chromium_src/third_party/blink/renderer/modules/storage/storage_controller.h b/chromium_src/third_party/blink/renderer/modules/storage/storage_controller.h new file mode 100644 index 000000000000..4a8e1f498287 --- /dev/null +++ b/chromium_src/third_party/blink/renderer/modules/storage/storage_controller.h @@ -0,0 +1,18 @@ +/* Copyright (c) 2020 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_CHROMIUM_SRC_THIRD_PARTY_BLINK_RENDERER_MODULES_STORAGE_STORAGE_CONTROLLER_H_ +#define BRAVE_CHROMIUM_SRC_THIRD_PARTY_BLINK_RENDERER_MODULES_STORAGE_STORAGE_CONTROLLER_H_ + +#define BRAVE_STORAGE_CONTROLLER_H \ + public: \ + static bool CanAccessStorageAreaWithoutEphemeral( \ + LocalFrame* frame, StorageArea::StorageType type); + +#include "../../../../../../../third_party/blink/renderer/modules/storage/storage_controller.h" + +#undef BRAVE_STORAGE_CONTROLLER_H + +#endif // BRAVE_CHROMIUM_SRC_THIRD_PARTY_BLINK_RENDERER_MODULES_STORAGE_STORAGE_CONTROLLER_H_ diff --git a/patches/third_party-blink-renderer-modules-storage-storage_controller.h.patch b/patches/third_party-blink-renderer-modules-storage-storage_controller.h.patch new file mode 100644 index 000000000000..ac56cc46f47c --- /dev/null +++ b/patches/third_party-blink-renderer-modules-storage-storage_controller.h.patch @@ -0,0 +1,12 @@ +diff --git a/third_party/blink/renderer/modules/storage/storage_controller.h b/third_party/blink/renderer/modules/storage/storage_controller.h +index 554f6cbaadec5b247452b68ffe332d1210cd4a81..6d8e3adec71bbbf7782671f4d0138f30ecebac39 100644 +--- a/third_party/blink/renderer/modules/storage/storage_controller.h ++++ b/third_party/blink/renderer/modules/storage/storage_controller.h +@@ -96,6 +96,7 @@ class MODULES_EXPORT StorageController : public mojom::blink::DomStorageClient { + return task_runner_; + } + ++ BRAVE_STORAGE_CONTROLLER_H + private: + void EnsureLocalStorageNamespaceCreated(); +