diff --git a/browser/ephemeral_storage/ephemeral_storage_browsertest.cc b/browser/ephemeral_storage/ephemeral_storage_browsertest.cc index 7b7a35bfe640..e57d861b6dc6 100644 --- a/browser/ephemeral_storage/ephemeral_storage_browsertest.cc +++ b/browser/ephemeral_storage/ephemeral_storage_browsertest.cc @@ -70,15 +70,30 @@ content::EvalJsResult GetCookiesInFrame(RenderFrameHost* host) { return content::EvalJs(host, "document.cookie"); } +content::EvalJsResult GetStorageInFrame(RenderFrameHost* host, + StorageType storage_type) { + std::string script = base::StringPrintf("%sStorage;", ToString(storage_type)); + return content::EvalJs(host, script); +} + +void AssertEmptyInFrame(RenderFrameHost* frame) { + EXPECT_EQ(nullptr, GetStorageInFrame(frame, StorageType::Local)); + EXPECT_EQ(nullptr, GetStorageInFrame(frame, StorageType::Session)); + EXPECT_EQ("", GetCookiesInFrame(frame)); +} + +void AssertEmptyInSubframes(WebContents* web_contents) { + RenderFrameHost* main_frame = web_contents->GetMainFrame(); + AssertEmptyInFrame(content::ChildFrameAt(main_frame, 0)); + AssertEmptyInFrame(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( - net::features::kBraveEphemeralStorage); - } + EphemeralStorageBaseBrowserTest() + : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {} void SetUpOnMainThread() override { InProcessBrowserTest::SetUpOnMainThread(); @@ -116,6 +131,21 @@ class EphemeralStorageBrowserTest : public InProcessBrowserTest { content_settings, brave_shields::ControlType::ALLOW, GURL()); } + void BlockThirdPartyCookies() { + auto* content_settings = + HostContentSettingsMapFactory::GetForProfile(browser()->profile()); + brave_shields::SetCookieControlType( + content_settings, brave_shields::ControlType::BLOCK_THIRD_PARTY, + GURL()); + } + + void BlockALLCookies() { + auto* content_settings = + HostContentSettingsMapFactory::GetForProfile(browser()->profile()); + brave_shields::SetCookieControlType( + content_settings, brave_shields::ControlType::BLOCK, GURL()); + } + void SetValuesInFrame(RenderFrameHost* frame, std::string storage_value, std::string cookie_value) { @@ -180,11 +210,19 @@ class EphemeralStorageBrowserTest : public InProcessBrowserTest { GURL c_site_ephemeral_storage_url_; private: - DISALLOW_COPY_AND_ASSIGN(EphemeralStorageBrowserTest); + DISALLOW_COPY_AND_ASSIGN(EphemeralStorageBaseBrowserTest); +}; + +class EphemeralStorageBrowserTest : public EphemeralStorageBaseBrowserTest { + public: + EphemeralStorageBrowserTest() { + scoped_feature_list_.InitAndEnableFeature( + net::features::kBraveEphemeralStorage); + } }; IN_PROC_BROWSER_TEST_F(EphemeralStorageBrowserTest, StorageIsPartitioned) { - AllowAllCookies(); + BlockThirdPartyCookies(); WebContents* first_party_tab = LoadURLInNewTab(b_site_ephemeral_storage_url_); WebContents* site_a_tab1 = LoadURLInNewTab(a_site_ephemeral_storage_url_); @@ -263,7 +301,7 @@ IN_PROC_BROWSER_TEST_F(EphemeralStorageBrowserTest, StorageIsPartitioned) { IN_PROC_BROWSER_TEST_F(EphemeralStorageBrowserTest, NavigatingClearsEphemeralStorage) { - AllowAllCookies(); + BlockThirdPartyCookies(); ui_test_utils::NavigateToURL(browser(), a_site_ephemeral_storage_url_); auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); @@ -303,7 +341,7 @@ IN_PROC_BROWSER_TEST_F(EphemeralStorageBrowserTest, IN_PROC_BROWSER_TEST_F(EphemeralStorageBrowserTest, ClosingTabClearsEphemeralStorage) { - AllowAllCookies(); + BlockThirdPartyCookies(); WebContents* site_a_tab = LoadURLInNewTab(a_site_ephemeral_storage_url_); EXPECT_EQ(browser()->tab_strip_model()->count(), 2); @@ -353,7 +391,7 @@ IN_PROC_BROWSER_TEST_F(EphemeralStorageBrowserTest, IN_PROC_BROWSER_TEST_F(EphemeralStorageBrowserTest, ReloadDoesNotClearEphemeralStorage) { - AllowAllCookies(); + BlockThirdPartyCookies(); ui_test_utils::NavigateToURL(browser(), a_site_ephemeral_storage_url_); auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); @@ -392,7 +430,7 @@ IN_PROC_BROWSER_TEST_F(EphemeralStorageBrowserTest, IN_PROC_BROWSER_TEST_F(EphemeralStorageBrowserTest, EphemeralStorageDoesNotLeakBetweenProfiles) { - AllowAllCookies(); + BlockThirdPartyCookies(); ui_test_utils::NavigateToURL(browser(), a_site_ephemeral_storage_url_); auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); @@ -457,7 +495,7 @@ IN_PROC_BROWSER_TEST_F(EphemeralStorageBrowserTest, IN_PROC_BROWSER_TEST_F(EphemeralStorageBrowserTest, NavigationCookiesArePartitioned) { - AllowAllCookies(); + BlockThirdPartyCookies(); GURL a_site_set_cookie_url = https_server_.GetURL( "a.com", "/set-cookie?name=acom;path=/;SameSite=None;Secure"); @@ -510,7 +548,7 @@ IN_PROC_BROWSER_TEST_F(EphemeralStorageBrowserTest, IN_PROC_BROWSER_TEST_F(EphemeralStorageBrowserTest, FirstPartyNestedInThirdParty) { - AllowAllCookies(); + BlockThirdPartyCookies(); auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); @@ -554,3 +592,338 @@ IN_PROC_BROWSER_TEST_F(EphemeralStorageBrowserTest, EXPECT_EQ("third-party-a.com", third_party_values.session_storage); EXPECT_EQ("name=third-party-a.com", third_party_values.cookies); } + +IN_PROC_BROWSER_TEST_F(EphemeralStorageBrowserTest, + UseNonEphmeralStorageWhenThirdPartyCookiesAllowed) { + 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); + + EXPECT_EQ("from=b.com", first_party_values.main_frame.cookies); + EXPECT_EQ("from=b.com", first_party_values.iframe_1.cookies); + EXPECT_EQ("from=b.com", first_party_values.iframe_2.cookies); + + 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); + + EXPECT_EQ("", site_a_tab_values.main_frame.cookies); + EXPECT_EQ("from=b.com", site_a_tab_values.iframe_1.cookies); + EXPECT_EQ("from=b.com", site_a_tab_values.iframe_2.cookies); +} + +IN_PROC_BROWSER_TEST_F( + EphemeralStorageBrowserTest, + UseNonEphmeralNavigateCookiesWhenThirdPartyCookiesAllowed) { + AllowAllCookies(); + + GURL b_site_set_cookie_url = https_server_.GetURL( + "b.com", "/set-cookie?name=bcom;path=/;SameSite=None;Secure"); + + ui_test_utils::NavigateToURL(browser(), b_site_set_cookie_url); + ui_test_utils::NavigateToURL(browser(), a_site_ephemeral_storage_url_); + + std::string a_cookie = + content::GetCookies(browser()->profile(), GURL("https://a.com/")); + std::string b_cookie = + content::GetCookies(browser()->profile(), GURL("https://b.com/")); + EXPECT_EQ("", a_cookie); + EXPECT_EQ("name=bcom", b_cookie); + + // The third-party iframe should have the b.com cookie for third-party + // cookies is enabled. + auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); + RenderFrameHost* main_frame = web_contents->GetMainFrame(); + RenderFrameHost* iframe_a = content::ChildFrameAt(main_frame, 0); + RenderFrameHost* iframe_b = content::ChildFrameAt(main_frame, 1); + ASSERT_EQ("", GetCookiesInFrame(main_frame)); + ASSERT_EQ("name=bcom", GetCookiesInFrame(iframe_a)); + ASSERT_EQ("name=bcom", GetCookiesInFrame(iframe_b)); +} + +IN_PROC_BROWSER_TEST_F(EphemeralStorageBrowserTest, + StoragesNotAccessiableWhenAllCookiesBlocked) { + BlockALLCookies(); + + 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"); + RenderFrameHost* main_frame = web_contents->GetMainFrame(); + SetCookieInFrame(main_frame, "name=bcom"); + + // The storage in the first-party iframes should not be accessiable when all + // cookies are blocked. + AssertEmptyInSubframes(web_contents); + + ui_test_utils::NavigateToURL(browser(), a_site_ephemeral_storage_url_); + auto* a_site_content = browser()->tab_strip_model()->GetActiveWebContents(); + + RenderFrameHost* a_site_main_frame = a_site_content->GetMainFrame(); + RenderFrameHost* a_site_iframe_a = + content::ChildFrameAt(a_site_main_frame, 0); + SetCookieInFrame(a_site_iframe_a, "name=acom"); + + // The storage in the third-party iframes should not accessiable when all + // cookies are blocked. + AssertEmptyInSubframes(a_site_content); +} + +IN_PROC_BROWSER_TEST_F(EphemeralStorageBrowserTest, + NavigateCookiesNotAccessiableWhenAllCookiesBlocked) { + BlockALLCookies(); + + GURL b_site_set_cookie_url = https_server_.GetURL( + "b.com", "/set-cookie?name=bcom;path=/;SameSite=None;Secure"); + + ui_test_utils::NavigateToURL(browser(), b_site_set_cookie_url); + ui_test_utils::NavigateToURL(browser(), a_site_ephemeral_storage_url_); + + std::string a_cookie = + content::GetCookies(browser()->profile(), GURL("https://a.com/")); + std::string b_cookie = + content::GetCookies(browser()->profile(), GURL("https://b.com/")); + EXPECT_EQ("", a_cookie); + EXPECT_EQ("", b_cookie); + + // The third-party iframe should not access to any cookies. + auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); + RenderFrameHost* main_frame = web_contents->GetMainFrame(); + RenderFrameHost* iframe_a = content::ChildFrameAt(main_frame, 0); + RenderFrameHost* iframe_b = content::ChildFrameAt(main_frame, 1); + ASSERT_EQ("", GetCookiesInFrame(main_frame)); + ASSERT_EQ("", GetCookiesInFrame(iframe_a)); + ASSERT_EQ("", GetCookiesInFrame(iframe_b)); + + content::NavigateIframeToURL(web_contents, "third_party_iframe_a", + b_site_set_cookie_url); + + ASSERT_EQ("", GetCookiesInFrame(iframe_a)); + ASSERT_EQ("", GetCookiesInFrame(iframe_b)); +} + +class EphemeralStorageDisabledBrowserTest + : public EphemeralStorageBaseBrowserTest { + public: + EphemeralStorageDisabledBrowserTest() { + scoped_feature_list_.InitAndDisableFeature( + net::features::kBraveEphemeralStorage); + } +}; + +IN_PROC_BROWSER_TEST_F(EphemeralStorageDisabledBrowserTest, + UseNonEphmeralStorageWhenThirdPartyCookiesAllowed) { + 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); + + EXPECT_EQ("from=b.com", first_party_values.main_frame.cookies); + EXPECT_EQ("from=b.com", first_party_values.iframe_1.cookies); + EXPECT_EQ("from=b.com", first_party_values.iframe_2.cookies); + + 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); + + EXPECT_EQ("", site_a_tab_values.main_frame.cookies); + EXPECT_EQ("from=b.com", site_a_tab_values.iframe_1.cookies); + EXPECT_EQ("from=b.com", site_a_tab_values.iframe_2.cookies); +} + +IN_PROC_BROWSER_TEST_F( + EphemeralStorageDisabledBrowserTest, + UseNonEphmeralNavigateCookiesWhenThirdPartyCookiesAllowed) { + AllowAllCookies(); + + GURL b_site_set_cookie_url = https_server_.GetURL( + "b.com", "/set-cookie?name=bcom;path=/;SameSite=None;Secure"); + + ui_test_utils::NavigateToURL(browser(), b_site_set_cookie_url); + ui_test_utils::NavigateToURL(browser(), a_site_ephemeral_storage_url_); + + std::string a_cookie = + content::GetCookies(browser()->profile(), GURL("https://a.com/")); + std::string b_cookie = + content::GetCookies(browser()->profile(), GURL("https://b.com/")); + EXPECT_EQ("", a_cookie); + EXPECT_EQ("name=bcom", b_cookie); + + // The third-party iframe should have the b.com cookie for third-party + // cookies is enabled. + auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); + RenderFrameHost* main_frame = web_contents->GetMainFrame(); + RenderFrameHost* iframe_a = content::ChildFrameAt(main_frame, 0); + RenderFrameHost* iframe_b = content::ChildFrameAt(main_frame, 1); + ASSERT_EQ("", GetCookiesInFrame(main_frame)); + ASSERT_EQ("name=bcom", GetCookiesInFrame(iframe_a)); + ASSERT_EQ("name=bcom", GetCookiesInFrame(iframe_b)); +} + +IN_PROC_BROWSER_TEST_F(EphemeralStorageDisabledBrowserTest, + StorageNotAccessiableWhenThirdPartyCookiesBlocked) { + BlockThirdPartyCookies(); + + 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); + + EXPECT_EQ("from=b.com", first_party_values.main_frame.cookies); + EXPECT_EQ("from=b.com", first_party_values.iframe_1.cookies); + EXPECT_EQ("from=b.com", first_party_values.iframe_2.cookies); + + 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. + AssertEmptyInSubframes(a_site_content); +} + +IN_PROC_BROWSER_TEST_F( + EphemeralStorageDisabledBrowserTest, + NavigateCookiesNotAccessibleWhenThirdPartyCookiesBlocked) { + BlockThirdPartyCookies(); + + GURL b_site_set_cookie_url = https_server_.GetURL( + "b.com", "/set-cookie?name=bcom;path=/;SameSite=None;Secure"); + + ui_test_utils::NavigateToURL(browser(), b_site_set_cookie_url); + ui_test_utils::NavigateToURL(browser(), a_site_ephemeral_storage_url_); + + std::string a_cookie = + content::GetCookies(browser()->profile(), GURL("https://a.com/")); + std::string b_cookie = + content::GetCookies(browser()->profile(), GURL("https://b.com/")); + EXPECT_EQ("", a_cookie); + EXPECT_EQ("name=bcom", b_cookie); + + // The third-party iframe should be empty for third-party + // cookies is disabled. + auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); + RenderFrameHost* main_frame = web_contents->GetMainFrame(); + RenderFrameHost* iframe_a = content::ChildFrameAt(main_frame, 0); + RenderFrameHost* iframe_b = content::ChildFrameAt(main_frame, 1); + ASSERT_EQ("", GetCookiesInFrame(main_frame)); + ASSERT_EQ("", GetCookiesInFrame(iframe_a)); + ASSERT_EQ("", GetCookiesInFrame(iframe_b)); +} + +IN_PROC_BROWSER_TEST_F(EphemeralStorageDisabledBrowserTest, + StoragesNotAccessiableWhenAllCookiesBlocked) { + BlockALLCookies(); + + 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"); + RenderFrameHost* main_frame = web_contents->GetMainFrame(); + SetCookieInFrame(main_frame, "name=bcom"); + + // The storage in the first-party iframes should not be accessiable when all + // cookies are blocked. + AssertEmptyInSubframes(web_contents); + + ui_test_utils::NavigateToURL(browser(), a_site_ephemeral_storage_url_); + auto* a_site_content = browser()->tab_strip_model()->GetActiveWebContents(); + + RenderFrameHost* a_site_main_frame = a_site_content->GetMainFrame(); + RenderFrameHost* a_site_iframe_a = + content::ChildFrameAt(a_site_main_frame, 0); + SetCookieInFrame(a_site_iframe_a, "name=acom"); + + // The storage in the third-party iframes should not accessiable when all + // cookies are blocked. + AssertEmptyInSubframes(a_site_content); +} + +IN_PROC_BROWSER_TEST_F(EphemeralStorageDisabledBrowserTest, + NavigateCookiesNotAccessiableWhenAllCookiesBlocked) { + BlockALLCookies(); + + GURL b_site_set_cookie_url = https_server_.GetURL( + "b.com", "/set-cookie?name=bcom;path=/;SameSite=None;Secure"); + + ui_test_utils::NavigateToURL(browser(), b_site_set_cookie_url); + ui_test_utils::NavigateToURL(browser(), a_site_ephemeral_storage_url_); + + std::string a_cookie = + content::GetCookies(browser()->profile(), GURL("https://a.com/")); + std::string b_cookie = + content::GetCookies(browser()->profile(), GURL("https://b.com/")); + EXPECT_EQ("", a_cookie); + EXPECT_EQ("", b_cookie); + + // The third-party iframe should not access to any cookies. + auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); + RenderFrameHost* main_frame = web_contents->GetMainFrame(); + RenderFrameHost* iframe_a = content::ChildFrameAt(main_frame, 0); + RenderFrameHost* iframe_b = content::ChildFrameAt(main_frame, 1); + ASSERT_EQ("", GetCookiesInFrame(main_frame)); + ASSERT_EQ("", GetCookiesInFrame(iframe_a)); + ASSERT_EQ("", GetCookiesInFrame(iframe_b)); + + content::NavigateIframeToURL(web_contents, "third_party_iframe_a", + b_site_set_cookie_url); + + ASSERT_EQ("", GetCookiesInFrame(iframe_a)); + ASSERT_EQ("", GetCookiesInFrame(iframe_b)); +} diff --git a/chromium_src/components/content_settings/browser/content_settings_manager_impl.cc b/chromium_src/components/content_settings/browser/content_settings_manager_impl.cc new file mode 100644 index 000000000000..f236d8dabc0d --- /dev/null +++ b/chromium_src/components/content_settings/browser/content_settings_manager_impl.cc @@ -0,0 +1,99 @@ +/* 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 "components/content_settings/browser/content_settings_manager_impl.h" + +#include "components/content_settings/browser/page_specific_content_settings.h" +#include "components/content_settings/core/browser/cookie_settings.h" +#include "components/page_load_metrics/browser/page_load_metrics_observer.h" + +namespace content_settings { +namespace { +void OnStorageAccessed(int process_id, + int frame_id, + const GURL& origin_url, + const GURL& top_origin_url, + bool blocked_by_policy, + page_load_metrics::StorageType storage_type); + +void OnDomStorageAccessed(int process_id, + int frame_id, + const GURL& origin_url, + const GURL& top_origin_url, + bool local, + bool blocked_by_policy); +} // namespace + +void ContentSettingsManagerImpl::AllowStorageAccessWithoutEphemeralStorage( + int32_t render_frame_id, + StorageType storage_type, + const url::Origin& origin, + const GURL& site_for_cookies, + const url::Origin& top_frame_origin, + base::OnceCallback callback) { + GURL url = origin.GetURL(); + bool allowed = cookie_settings_->IsCookieAccessAllowed(url, site_for_cookies, + top_frame_origin); + if (delegate_->AllowStorageAccess(render_process_id_, render_frame_id, + storage_type, url, allowed, &callback)) { + DCHECK(!callback); + return; + } + + switch (storage_type) { + case StorageType::DATABASE: + PageSpecificContentSettings::WebDatabaseAccessed( + render_process_id_, render_frame_id, url, !allowed); + break; + case StorageType::LOCAL_STORAGE: + OnDomStorageAccessed(render_process_id_, render_frame_id, url, + top_frame_origin.GetURL(), true, !allowed); + OnStorageAccessed(render_process_id_, render_frame_id, url, + top_frame_origin.GetURL(), !allowed, + page_load_metrics::StorageType::kLocalStorage); + break; + case StorageType::SESSION_STORAGE: + OnDomStorageAccessed(render_process_id_, render_frame_id, url, + top_frame_origin.GetURL(), false, !allowed); + OnStorageAccessed(render_process_id_, render_frame_id, url, + top_frame_origin.GetURL(), !allowed, + page_load_metrics::StorageType::kSessionStorage); + + break; + case StorageType::FILE_SYSTEM: + PageSpecificContentSettings::FileSystemAccessed( + render_process_id_, render_frame_id, url, !allowed); + OnStorageAccessed(render_process_id_, render_frame_id, url, + top_frame_origin.GetURL(), !allowed, + page_load_metrics::StorageType::kFileSystem); + break; + case StorageType::INDEXED_DB: + PageSpecificContentSettings::IndexedDBAccessed( + render_process_id_, render_frame_id, url, !allowed); + OnStorageAccessed(render_process_id_, render_frame_id, url, + top_frame_origin.GetURL(), !allowed, + page_load_metrics::StorageType::kIndexedDb); + break; + case StorageType::CACHE: + PageSpecificContentSettings::CacheStorageAccessed( + render_process_id_, render_frame_id, url, !allowed); + OnStorageAccessed(render_process_id_, render_frame_id, url, + top_frame_origin.GetURL(), !allowed, + page_load_metrics::StorageType::kCacheStorage); + break; + case StorageType::WEB_LOCKS: + // State not persisted, no need to record anything. + break; + } + + std::move(callback).Run(allowed); +} +} // namespace content_settings + +#define IsCookieAccessAllowed IsCookieAccessOrEphemeralCookiesAccessAllowed + +#include "../../../../../components/content_settings/browser/content_settings_manager_impl.cc" + +#undef IsCookieAccessAllowed diff --git a/chromium_src/components/content_settings/browser/content_settings_manager_impl.h b/chromium_src/components/content_settings/browser/content_settings_manager_impl.h new file mode 100644 index 000000000000..f6927be167f3 --- /dev/null +++ b/chromium_src/components/content_settings/browser/content_settings_manager_impl.h @@ -0,0 +1,21 @@ +/* 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_COMPONENTS_CONTENT_SETTINGS_BROWSER_CONTENT_SETTINGS_MANAGER_IMPL_H_ +#define BRAVE_CHROMIUM_SRC_COMPONENTS_CONTENT_SETTINGS_BROWSER_CONTENT_SETTINGS_MANAGER_IMPL_H_ + +#define BRAVE_CONTENT_SETTINGS_MANAGER_IMPL_H \ + public: \ + void AllowStorageAccessWithoutEphemeralStorage( \ + int32_t render_frame_id, StorageType storage_type, \ + const url::Origin& origin, const GURL& site_for_cookies, \ + const url::Origin& top_frame_origin, \ + base::OnceCallback callback) override; + +#include "../../../../../components/content_settings/browser/content_settings_manager_impl.h" + +#undef BRAVE_CONTENT_SETTINGS_MANAGER_IMPL_H + +#endif // BRAVE_CHROMIUM_SRC_COMPONENTS_CONTENT_SETTINGS_BROWSER_CONTENT_SETTINGS_MANAGER_IMPL_H_ diff --git a/chromium_src/components/content_settings/core/common/cookie_settings_base.cc b/chromium_src/components/content_settings/core/common/cookie_settings_base.cc index 8c44afcdd554..7096fdf148eb 100644 --- a/chromium_src/components/content_settings/core/common/cookie_settings_base.cc +++ b/chromium_src/components/content_settings/core/common/cookie_settings_base.cc @@ -11,6 +11,7 @@ #include "components/content_settings/core/common/content_settings.h" #include "components/content_settings/core/common/content_settings_pattern.h" #include "components/content_settings/core/common/features.h" +#include "net/base/features.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" #include "url/gurl.h" #include "url/origin.h" @@ -171,6 +172,33 @@ bool CookieSettingsBase::IsCookieAccessAllowed( return IsChromiumCookieAccessAllowed(url, site_for_cookies, top_frame_origin); } +bool CookieSettingsBase::IsAllCookiesBlocked( + const GURL& url, + const GURL& site_for_cookies, + const base::Optional& top_frame_origin) const { + // Get content settings only - do not consider default 3rd-party blocking. + ContentSetting setting; + GetCookieSettingInternal( + url, top_frame_origin ? top_frame_origin->GetURL() : site_for_cookies, + false, nullptr, &setting); + return setting == CONTENT_SETTING_BLOCK; +} + +bool CookieSettingsBase::IsCookieAccessOrEphemeralCookiesAccessAllowed( + const GURL& url, + const GURL& site_for_cookies, + const base::Optional& top_frame_origin) const { + if (IsCookieAccessAllowed(url, site_for_cookies, top_frame_origin)) + return true; + if (IsAllCookiesBlocked(url, site_for_cookies, top_frame_origin)) + return false; + if (!base::FeatureList::IsEnabled(net::features::kBraveEphemeralStorage)) + return false; + if (!top_frame_origin.has_value()) + return false; + return *top_frame_origin != url::Origin::Create(url); +} + } // namespace content_settings #define IsCookieAccessAllowed IsChromiumCookieAccessAllowed diff --git a/chromium_src/components/content_settings/core/common/cookie_settings_base.h b/chromium_src/components/content_settings/core/common/cookie_settings_base.h index 1ba8ef436568..78fdeb250d0e 100644 --- a/chromium_src/components/content_settings/core/common/cookie_settings_base.h +++ b/chromium_src/components/content_settings/core/common/cookie_settings_base.h @@ -6,13 +6,20 @@ #ifndef BRAVE_CHROMIUM_SRC_COMPONENTS_CONTENT_SETTINGS_CORE_COMMON_COOKIE_SETTINGS_BASE_H_ #define BRAVE_CHROMIUM_SRC_COMPONENTS_CONTENT_SETTINGS_CORE_COMMON_COOKIE_SETTINGS_BASE_H_ -#define BRAVE_COOKIE_SETTINGS_BASE_H \ - private: \ - bool IsChromiumCookieAccessAllowed(const GURL& url, \ - const GURL& first_party_url) const; \ - bool IsChromiumCookieAccessAllowed( \ - const GURL& url, \ - const GURL& site_for_cookies, \ +#define BRAVE_COOKIE_SETTINGS_BASE_H \ + private: \ + bool IsChromiumCookieAccessAllowed(const GURL& url, \ + const GURL& first_party_url) const; \ + bool IsChromiumCookieAccessAllowed( \ + const GURL& url, const GURL& site_for_cookies, \ + const base::Optional& top_frame_origin) const; \ + bool IsAllCookiesBlocked( \ + const GURL& url, const GURL& site_for_cookies, \ + const base::Optional& top_frame_origin) const; \ + \ + public: \ + bool IsCookieAccessOrEphemeralCookiesAccessAllowed( \ + const GURL& url, const GURL& site_for_cookies, \ const base::Optional& top_frame_origin) const; #include "../../../../../../components/content_settings/core/common/cookie_settings_base.h" diff --git a/chromium_src/net/base/network_delegate.cc b/chromium_src/net/base/network_delegate.cc new file mode 100644 index 000000000000..48d03953ff34 --- /dev/null +++ b/chromium_src/net/base/network_delegate.cc @@ -0,0 +1,26 @@ +/* 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 "net/base/network_delegate.h" + +#include "net/url_request/url_request.h" + +namespace net { +bool NetworkDelegate::OnCanGetCookiesWithoutEphemeralCookies( + const URLRequest& request, + bool allowed_from_caller) { + return OnCanGetCookies(request, allowed_from_caller); +} + +bool NetworkDelegate::OnCanSetCookieWithoutEphemeralCookies( + const URLRequest& request, + const CanonicalCookie& cookie, + CookieOptions* options, + bool allowed_from_caller) { + return OnCanSetCookie(request, cookie, options, allowed_from_caller); +} +} // namespace net + +#include "../../../../net/base/network_delegate.cc" diff --git a/chromium_src/net/base/network_delegate.h b/chromium_src/net/base/network_delegate.h new file mode 100644 index 000000000000..16a081977081 --- /dev/null +++ b/chromium_src/net/base/network_delegate.h @@ -0,0 +1,20 @@ +/* Copyright (c) 2019 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_NET_BASE_NETWORK_DELEGATE_H_ +#define BRAVE_CHROMIUM_SRC_NET_BASE_NETWORK_DELEGATE_H_ + +#define BRAVE_NETWORK_DELEGATE_H \ + virtual bool OnCanGetCookiesWithoutEphemeralCookies( \ + const URLRequest& request, bool allowed_from_caller); \ + virtual bool OnCanSetCookieWithoutEphemeralCookies( \ + const URLRequest& request, const CanonicalCookie& cookie, \ + CookieOptions* options, bool allowed_from_caller); + +#include "../../../../net/base/network_delegate.h" + +#undef BRAVE_NETWORK_DELEGATE_H + +#endif // BRAVE_CHROMIUM_SRC_NET_BASE_NETWORK_DELEGATE_H_ diff --git a/chromium_src/net/url_request/url_request_http_job.cc b/chromium_src/net/url_request/url_request_http_job.cc index 20b503402524..2c8c009184cc 100644 --- a/chromium_src/net/url_request/url_request_http_job.cc +++ b/chromium_src/net/url_request/url_request_http_job.cc @@ -6,32 +6,39 @@ #include "net/url_request/url_request_http_job.h" #include "base/bind.h" -#include "net/base/features.h" #include "net/base/isolation_info.h" #include "net/cookies/cookie_monster.h" #include "net/url_request/url_request.h" -namespace { +namespace net { -bool ShouldUseEphemeralStorage(net::URLRequestHttpJob* http_job) { - if (!base::FeatureList::IsEnabled(net::features::kBraveEphemeralStorage)) +bool URLRequestHttpJob::CanGetNonEphemeralCookies() { + if (request_info_.privacy_mode != PRIVACY_MODE_DISABLED) return false; - - const net::IsolationInfo& isolation_info = - http_job->request()->isolation_info(); - if (!isolation_info.top_frame_origin().has_value() || - !isolation_info.frame_origin().has_value()) + if (!request_) return false; - if (*isolation_info.top_frame_origin() == *isolation_info.frame_origin()) + if (!request_->network_delegate()) return false; + return request_->network_delegate()->OnCanGetCookiesWithoutEphemeralCookies( + *request_, /*allowed_from_caller=*/true); +} - return true; +bool URLRequestHttpJob::CanSetNonEphemeralCookie( + const net::CanonicalCookie& cookie, + CookieOptions* options) { + if (!request_) + return false; + if (!request_->network_delegate()) + return false; + return request_->network_delegate()->OnCanSetCookieWithoutEphemeralCookies( + *request_, cookie, options, + /*allowed_from_caller=*/true); } -} // namespace +} // namespace net #define BRAVE_ADDCOOKIEHEADERANDSTART \ - if (ShouldUseEphemeralStorage(this)) \ + if (!CanGetNonEphemeralCookies()) \ static_cast(cookie_store) \ ->GetEphemeralCookieListWithOptionsAsync( \ request_->url(), \ @@ -41,7 +48,7 @@ bool ShouldUseEphemeralStorage(net::URLRequestHttpJob* http_job) { else #define BRAVE_SAVECOOKIESANDNOTIFYHEADERSCOMPLETE \ - if (ShouldUseEphemeralStorage(this)) \ + if (!CanSetNonEphemeralCookie(*cookie, &options)) \ static_cast(request_->context()->cookie_store()) \ ->SetEphemeralCanonicalCookieAsync( \ std::move(cookie), request_->url(), \ diff --git a/chromium_src/net/url_request/url_request_http_job.h b/chromium_src/net/url_request/url_request_http_job.h new file mode 100644 index 000000000000..c826ead5b36e --- /dev/null +++ b/chromium_src/net/url_request/url_request_http_job.h @@ -0,0 +1,20 @@ +/* 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_NET_URL_REQUEST_URL_REQUEST_HTTP_JOB_H_ +#define BRAVE_CHROMIUM_SRC_NET_URL_REQUEST_URL_REQUEST_HTTP_JOB_H_ + +#define ShouldFixMismatchedContentLength \ + CanGetNonEphemeralCookies(); \ + bool CanSetNonEphemeralCookie(const net::CanonicalCookie&, CookieOptions*); \ + bool CanSetCookieIncludingEphemeral(const net::CanonicalCookie&, \ + CookieOptions*); \ + bool ShouldFixMismatchedContentLength + +#include "../../../../net/url_request/url_request_http_job.h" + +#undef ShouldFixMismatchedContentLength + +#endif // BRAVE_CHROMIUM_SRC_NET_URL_REQUEST_URL_REQUEST_HTTP_JOB_H_ diff --git a/chromium_src/services/network/network_service_network_delegate.cc b/chromium_src/services/network/network_service_network_delegate.cc new file mode 100644 index 000000000000..3ad4bde832f5 --- /dev/null +++ b/chromium_src/services/network/network_service_network_delegate.cc @@ -0,0 +1,77 @@ +/* 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 "services/network/network_service_network_delegate.h" + +#include "net/url_request/url_request.h" +#include "services/network/cookie_manager.h" +#include "services/network/url_loader.h" +#include "url/gurl.h" + +#if !defined(OS_IOS) +#include "services/network/websocket.h" +#endif + +namespace network { + +bool NetworkServiceNetworkDelegate::OnCanGetCookies( + const net::URLRequest& request, + bool allowed_from_caller) { + bool allowed = + allowed_from_caller && + network_context_->cookie_manager() + ->cookie_settings() + .IsCookieAccessOrEphemeralCookiesAccessAllowed( + request.url(), request.site_for_cookies().RepresentativeUrl(), + request.isolation_info().top_frame_origin()); + + if (!allowed) + return false; + + URLLoader* url_loader = URLLoader::ForRequest(request); + if (url_loader) + return url_loader->AllowCookies(request.url(), request.site_for_cookies()); +#if !defined(OS_IOS) + WebSocket* web_socket = WebSocket::ForRequest(request); + if (web_socket) + return web_socket->AllowCookies(request.url()); +#endif // !defined(OS_IOS) + return true; +} + +bool NetworkServiceNetworkDelegate::OnCanSetCookie( + const net::URLRequest& request, + const net::CanonicalCookie& cookie, + net::CookieOptions* options, + bool allowed_from_caller) { + bool allowed = + allowed_from_caller && + network_context_->cookie_manager() + ->cookie_settings() + .IsCookieAccessOrEphemeralCookiesAccessAllowed( + request.url(), request.site_for_cookies().RepresentativeUrl(), + request.isolation_info().top_frame_origin()); + if (!allowed) + return false; + URLLoader* url_loader = URLLoader::ForRequest(request); + if (url_loader) + return url_loader->AllowCookies(request.url(), request.site_for_cookies()); +#if !defined(OS_IOS) + WebSocket* web_socket = WebSocket::ForRequest(request); + if (web_socket) + return web_socket->AllowCookies(request.url()); +#endif // !defined(OS_IOS) + return true; +} + +} // namespace network + +#define OnCanGetCookies OnCanGetCookiesWithoutEphemeralCookies +#define OnCanSetCookie OnCanSetCookieWithoutEphemeralCookies + +#include "../../../../../services/network/network_service_network_delegate.cc" + +#undef OnCanSetCookie +#undef OnCanGetCookies diff --git a/chromium_src/services/network/network_service_network_delegate.h b/chromium_src/services/network/network_service_network_delegate.h new file mode 100644 index 000000000000..e2e7e7e45fbd --- /dev/null +++ b/chromium_src/services/network/network_service_network_delegate.h @@ -0,0 +1,21 @@ +/* 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_SERVICES_NETWORK_NETWORK_SERVICE_NETWORK_DELEGATE_H_ +#define BRAVE_CHROMIUM_SRC_SERVICES_NETWORK_NETWORK_SERVICE_NETWORK_DELEGATE_H_ + +#define BRAVE_NETWORK_SERVICE_NETWORK_DELEGATE_H \ + private: \ + bool OnCanGetCookiesWithoutEphemeralCookies( \ + const net::URLRequest& request, bool allowed_from_caller) override; \ + bool OnCanSetCookieWithoutEphemeralCookies( \ + const net::URLRequest& request, const net::CanonicalCookie& cookie, \ + net::CookieOptions* options, bool allowed_from_caller) override; + +#include "../../../../../services/network/network_service_network_delegate.h" + +#undef BRAVE_NETWORK_SERVICE_NETWORK_DELEGATE_H + +#endif // BRAVE_CHROMIUM_SRC_SERVICES_NETWORK_NETWORK_SERVICE_NETWORK_DELEGATE_H_ diff --git a/chromium_src/services/network/restricted_cookie_manager.cc b/chromium_src/services/network/restricted_cookie_manager.cc index e43a45bdc709..a14f1fb43eb0 100644 --- a/chromium_src/services/network/restricted_cookie_manager.cc +++ b/chromium_src/services/network/restricted_cookie_manager.cc @@ -7,22 +7,27 @@ #include "net/base/features.h" #include "net/cookies/cookie_monster.h" +#include "services/network/cookie_settings.h" + +namespace network { namespace { -bool ShouldUseEphemeralStorage(const GURL& url, +bool ShouldUseEphemeralStorage(const CookieSettings* cookie_settings, + const GURL& url, + const net::SiteForCookies& site_for_cookies, const url::Origin& top_frame_origin) { - if (!base::FeatureList::IsEnabled(net::features::kBraveEphemeralStorage)) - return false; - if (url::Origin::Create(url) == top_frame_origin) - return false; - return true; + return !cookie_settings->IsCookieAccessAllowed( + url, site_for_cookies.RepresentativeUrl(), top_frame_origin); } } // namespace +} // namespace network + #define BRAVE_GETALLFORURL \ - if (ShouldUseEphemeralStorage(url, top_frame_origin)) { \ + if (ShouldUseEphemeralStorage(cookie_settings_, url, site_for_cookies, \ + top_frame_origin)) { \ static_cast(cookie_store_) \ ->GetEphemeralCookieListWithOptionsAsync( \ url, top_frame_origin.GetURL(), net_options, \ @@ -34,7 +39,8 @@ bool ShouldUseEphemeralStorage(const GURL& url, } else // NOLINT #define BRAVE_SETCANONICALCOOKIE \ - if (ShouldUseEphemeralStorage(url, top_frame_origin)) { \ + if (ShouldUseEphemeralStorage(cookie_settings_, url, site_for_cookies, \ + top_frame_origin)) { \ static_cast(cookie_store_) \ ->SetEphemeralCanonicalCookieAsync( \ std::move(sanitized_cookie), origin_.GetURL(), \ @@ -45,4 +51,8 @@ bool ShouldUseEphemeralStorage(const GURL& url, std::move(callback))); \ } else // NOLINT +#define IsCookieAccessAllowed IsCookieAccessOrEphemeralCookiesAccessAllowed + #include "../../../../../services/network/restricted_cookie_manager.cc" + +#undef IsCookieAccessAllowed diff --git a/chromium_src/third_party/blink/public/platform/web_content_settings_client.h b/chromium_src/third_party/blink/public/platform/web_content_settings_client.h index c5df224a3598..6b8e7ed71a9e 100644 --- a/chromium_src/third_party/blink/public/platform/web_content_settings_client.h +++ b/chromium_src/third_party/blink/public/platform/web_content_settings_client.h @@ -16,6 +16,10 @@ virtual BraveFarblingLevel GetBraveFarblingLevel() { \ return BraveFarblingLevel::OFF; \ } \ + virtual bool AllowStorageAccessWithoutEphemeralStorageSync( \ + StorageType storage_type) { \ + return true; \ + } \ virtual bool AllowStorageAccessSync #include "../../../../../../third_party/blink/public/platform/web_content_settings_client.h" 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 3e03e94a2b55..d68be5c7bb78 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 @@ -6,6 +6,7 @@ #include "../../../../../../../third_party/blink/renderer/modules/storage/dom_window_storage.cc" #include "net/base/features.h" #include "third_party/blink/public/common/dom_storage/session_storage_namespace_id.h" +#include "third_party/blink/public/platform/web_content_settings_client.h" #include "third_party/blink/public/web/web_view_client.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/exported/web_view_impl.h" @@ -42,6 +43,22 @@ void MaybeClearAccessDeniedException(StorageArea* storage, } } +bool CanAccessStorageAreaWithoutEphemeralStorage( + LocalFrame* frame, + StorageArea::StorageType type) { + if (auto* settings_client = frame->GetContentSettingsClient()) { + switch (type) { + case StorageArea::StorageType::kLocalStorage: + return settings_client->AllowStorageAccessWithoutEphemeralStorageSync( + WebContentSettingsClient::StorageType::kLocalStorage); + case StorageArea::StorageType::kSessionStorage: + return settings_client->AllowStorageAccessWithoutEphemeralStorageSync( + WebContentSettingsClient::StorageType::kSessionStorage); + } + } + return true; +} + } // namespace // EphemeralStorageNamespace manage ephemeral storage namespaces for a @@ -170,17 +187,15 @@ StorageArea* BraveDOMWindowStorage::sessionStorage( DOMWindowStorage::From(*window).sessionStorage(exception_state); MaybeClearAccessDeniedException(storage, *window, &exception_state); - if (!base::FeatureList::IsEnabled(net::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 (CanAccessStorageAreaWithoutEphemeralStorage( + window->GetFrame(), StorageArea::StorageType::kSessionStorage)) + return storage; + return ephemeralSessionStorage(); } @@ -210,17 +225,15 @@ StorageArea* BraveDOMWindowStorage::localStorage( auto* storage = DOMWindowStorage::From(*window).localStorage(exception_state); MaybeClearAccessDeniedException(storage, *window, &exception_state); - if (!base::FeatureList::IsEnabled(net::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 (CanAccessStorageAreaWithoutEphemeralStorage( + window->GetFrame(), StorageArea::StorageType::kLocalStorage)) + return storage; + return ephemeralLocalStorage(); } diff --git a/components/content_settings/renderer/brave_content_settings_agent_impl.cc b/components/content_settings/renderer/brave_content_settings_agent_impl.cc index cb1362c70d33..52ce9d1f896f 100644 --- a/components/content_settings/renderer/brave_content_settings_agent_impl.cc +++ b/components/content_settings/renderer/brave_content_settings_agent_impl.cc @@ -250,4 +250,16 @@ bool BraveContentSettingsAgentImpl::AllowAutoplay(bool play_requested) { return allow; } +bool BraveContentSettingsAgentImpl:: + AllowStorageAccessWithoutEphemeralStorageSync(StorageType storage_type) { + blink::WebLocalFrame* frame = render_frame()->GetWebFrame(); + bool result = false; + GetContentSettingsManager().AllowStorageAccessWithoutEphemeralStorage( + routing_id(), ConvertToMojoStorageType(storage_type), + frame->GetSecurityOrigin(), + frame->GetDocument().SiteForCookies().RepresentativeUrl(), + frame->GetDocument().TopFrameOrigin(), &result); + return result; +} + } // namespace content_settings diff --git a/components/content_settings/renderer/brave_content_settings_agent_impl.h b/components/content_settings/renderer/brave_content_settings_agent_impl.h index e474543d377a..87c1655d19af 100644 --- a/components/content_settings/renderer/brave_content_settings_agent_impl.h +++ b/components/content_settings/renderer/brave_content_settings_agent_impl.h @@ -29,6 +29,8 @@ class BraveContentSettingsAgentImpl : public ContentSettingsAgentImpl { bool should_whitelist, std::unique_ptr delegate); ~BraveContentSettingsAgentImpl() override; + bool AllowStorageAccessWithoutEphemeralStorageSync( + StorageType storage_type) override; protected: bool AllowScript(bool enabled_per_settings) override; diff --git a/components/content_settings/renderer/brave_content_settings_agent_impl_autoplay_browsertest.cc b/components/content_settings/renderer/brave_content_settings_agent_impl_autoplay_browsertest.cc index cffc6af71198..0ceb82e5cabb 100644 --- a/components/content_settings/renderer/brave_content_settings_agent_impl_autoplay_browsertest.cc +++ b/components/content_settings/renderer/brave_content_settings_agent_impl_autoplay_browsertest.cc @@ -46,6 +46,14 @@ class MockContentSettingsManagerImpl : public mojom::ContentSettingsManager { log_->on_content_blocked_type = type; } + void AllowStorageAccessWithoutEphemeralStorage( + int32_t render_frame_id, + StorageType storage_type, + const url::Origin& origin, + const GURL& site_for_cookies, + const url::Origin& top_frame_origin, + base::OnceCallback callback) override {} + private: Log* log_; }; diff --git a/patches/components-content_settings-browser-content_settings_manager_impl.h.patch b/patches/components-content_settings-browser-content_settings_manager_impl.h.patch new file mode 100644 index 000000000000..faae39c2e6ac --- /dev/null +++ b/patches/components-content_settings-browser-content_settings_manager_impl.h.patch @@ -0,0 +1,12 @@ +diff --git a/components/content_settings/browser/content_settings_manager_impl.h b/components/content_settings/browser/content_settings_manager_impl.h +index 09a41c1061e1a150180abd22e8b99ea65306a531..a779dd2a7c4e7c16cc47982361f356767b387446 100644 +--- a/components/content_settings/browser/content_settings_manager_impl.h ++++ b/components/content_settings/browser/content_settings_manager_impl.h +@@ -65,6 +65,7 @@ class ContentSettingsManagerImpl + void OnContentBlocked(int32_t render_frame_id, + ContentSettingsType type) override; + ++ BRAVE_COOKIE_SETTINGS_BASE_H + private: + ContentSettingsManagerImpl(content::RenderProcessHost* render_process_host, + std::unique_ptr delegate); diff --git a/patches/components-content_settings-common-content_settings_manager.mojom.patch b/patches/components-content_settings-common-content_settings_manager.mojom.patch new file mode 100644 index 000000000000..4520ef52be88 --- /dev/null +++ b/patches/components-content_settings-common-content_settings_manager.mojom.patch @@ -0,0 +1,18 @@ +diff --git a/components/content_settings/common/content_settings_manager.mojom b/components/content_settings/common/content_settings_manager.mojom +index 45b62cf62ec7a1d9245b3341becc01495f0ef0cf..371669ddf73c586189a1f4c7b26a2855f9c17947 100644 +--- a/components/content_settings/common/content_settings_manager.mojom ++++ b/components/content_settings/common/content_settings_manager.mojom +@@ -42,4 +42,13 @@ interface ContentSettingsManager { + // Tells the browser that content in the current page was blocked due to the + // user's content settings. + OnContentBlocked(int32 render_frame_id, ContentSettingsType type); ++ ++ // Check whether storage access request is granted originally. ++ [Sync] ++ AllowStorageAccessWithoutEphemeralStorage( ++ int32 render_frame_id, ++ StorageType storage_type, ++ url.mojom.Origin origin, ++ url.mojom.Url site_for_cookies, ++ url.mojom.Origin top_frame_origin) => (bool allowed); + }; diff --git a/patches/net-base-network_delegate.h.patch b/patches/net-base-network_delegate.h.patch new file mode 100644 index 000000000000..3ee3afda8d11 --- /dev/null +++ b/patches/net-base-network_delegate.h.patch @@ -0,0 +1,12 @@ +diff --git a/net/base/network_delegate.h b/net/base/network_delegate.h +index c00f0ccd3b5a8bf8973b359cfc7880355292be03..6626c98567cc5c7bd2f48d63647e3ff5f96b1b6a 100644 +--- a/net/base/network_delegate.h ++++ b/net/base/network_delegate.h +@@ -97,6 +97,7 @@ class NET_EXPORT NetworkDelegate { + bool CanUseReportingClient(const url::Origin& origin, + const GURL& endpoint) const; + ++ BRAVE_NETWORK_DELEGATE_H + protected: + THREAD_CHECKER(thread_checker_); + diff --git a/patches/net-url_request-url_request_http_job.cc.patch b/patches/net-url_request-url_request_http_job.cc.patch index ee8f2ebd9826..ed42ec68b233 100644 --- a/patches/net-url_request-url_request_http_job.cc.patch +++ b/patches/net-url_request-url_request_http_job.cc.patch @@ -1,8 +1,8 @@ diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc -index f5e754f4ea0288a685a6932b00f692e3c6638621..d7da91c3607d205fd19cae3be369d4e58989f8bb 100644 +index c9985fdde420aea6429fac17cbb1e695d2d311f1..57f4a32e9cce3d189c2987dca2eac9f83d737a54 100644 --- a/net/url_request/url_request_http_job.cc +++ b/net/url_request/url_request_http_job.cc -@@ -583,6 +583,7 @@ void URLRequestHttpJob::AddCookieHeaderAndStart() { +@@ -577,6 +577,7 @@ void URLRequestHttpJob::AddCookieHeaderAndStart() { net::cookie_util::ComputeSameSiteContextForRequest( request_->method(), request_->url(), request_->site_for_cookies(), request_->initiator(), force_ignore_site_for_cookies)); @@ -10,7 +10,7 @@ index f5e754f4ea0288a685a6932b00f692e3c6638621..d7da91c3607d205fd19cae3be369d4e5 cookie_store->GetCookieListWithOptionsAsync( request_->url(), options, base::BindOnce(&URLRequestHttpJob::SetCookieHeaderAndStart, -@@ -770,6 +771,7 @@ void URLRequestHttpJob::SaveCookiesAndNotifyHeadersComplete(int result) { +@@ -764,6 +765,7 @@ void URLRequestHttpJob::SaveCookiesAndNotifyHeadersComplete(int result) { continue; } diff --git a/patches/services-network-network_service_network_delegate.h.patch b/patches/services-network-network_service_network_delegate.h.patch new file mode 100644 index 000000000000..6b61b0197c70 --- /dev/null +++ b/patches/services-network-network_service_network_delegate.h.patch @@ -0,0 +1,12 @@ +diff --git a/services/network/network_service_network_delegate.h b/services/network/network_service_network_delegate.h +index 0926327d2a009550d91824ef87f06aa7c4482c64..52d9b8bcb10521adf5683631f763c37cfab94350 100644 +--- a/services/network/network_service_network_delegate.h ++++ b/services/network/network_service_network_delegate.h +@@ -33,6 +33,7 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkServiceNetworkDelegate + enable_referrers_ = enable_referrers; + } + ++ BRAVE_NETWORK_SERVICE_NETWORK_DELEGATE_H + private: + // net::NetworkDelegateImpl implementation. + int OnBeforeURLRequest(net::URLRequest* request,