diff --git a/browser/net/brave_network_delegate_browsertest.cc b/browser/net/brave_network_delegate_browsertest.cc index 6165cba75355..55e76931544c 100644 --- a/browser/net/brave_network_delegate_browsertest.cc +++ b/browser/net/brave_network_delegate_browsertest.cc @@ -17,6 +17,8 @@ #include "components/content_settings/core/common/pref_names.h" #include "components/network_session_configurator/common/network_switches.h" #include "components/prefs/pref_service.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/browser/web_contents.h" #include "content/public/common/content_paths.h" #include "content/public/test/browser_test_utils.h" #include "net/dns/mock_host_resolver.h" @@ -25,6 +27,22 @@ using net::test_server::EmbeddedTestServer; +bool NavigateRenderFrameToURL(content::RenderFrameHost* frame, + std::string iframe_id, + const GURL& url) { + std::string script = base::StringPrintf( + "setTimeout(\"" + "var iframes = document.getElementById('%s');iframes.src='%s';" + "\",0)", + iframe_id.c_str(), url.spec().c_str()); + + content::TestNavigationManager navigation_manager( + content::WebContents::FromRenderFrameHost(frame), url); + bool result = ExecuteScript(frame, script); + navigation_manager.WaitForNavigationFinished(); + return result; +} + class BraveNetworkDelegateBrowserTest : public InProcessBrowserTest { public: BraveNetworkDelegateBrowserTest() @@ -152,10 +170,10 @@ class BraveNetworkDelegateBrowserTest : public InProcessBrowserTest { url)); } - void NavigateFrameTo(const GURL url) { + void NavigateFrameTo(const GURL url, const std::string& id = "test") { content::WebContents* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); - EXPECT_TRUE(NavigateIframeToURL(web_contents, "test", url)); + EXPECT_TRUE(NavigateIframeToURL(web_contents, id, url)); } void BlockGoogleOAuthCookies() { @@ -257,6 +275,28 @@ IN_PROC_BROWSER_TEST_F(BraveNetworkDelegateBrowserTest, DefaultCookiesBlocked) { EXPECT_TRUE(cookie.empty()) << "Actual cookie: " << cookie; } +// 1stpartydomain.com -> 3rdpartydomain.com -> 1stpartydomain.com nested iframe +IN_PROC_BROWSER_TEST_F(BraveNetworkDelegateBrowserTest, + ThirdPartyCookiesBlockedNestedFirstPartyIframe) { + DefaultBlockThirdPartyCookies(); + + ui_test_utils::NavigateToURL(browser(), url_); + + auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); + + NavigateFrameTo( + embedded_test_server()->GetURL("b.com", "/iframe_cookie.html"), + "nested_iframe"); + + content::RenderFrameHost* child_frame = + content::ChildFrameAt(web_contents->GetMainFrame(), 0); + NavigateRenderFrameToURL(child_frame, "iframe_cookie", + subdomain_first_party_cookie_url_); + + ExpectCookiesOnHost(subdomain_first_party_cookie_url_, "name=subdomainacom"); +} + + IN_PROC_BROWSER_TEST_F(BraveNetworkDelegateBrowserTest, PrefToggleBlockAllToBlockThirdParty) { DefaultBlockAllCookies(); 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 new file mode 100644 index 000000000000..659bb021d64b --- /dev/null +++ b/chromium_src/components/content_settings/core/common/cookie_settings_base.cc @@ -0,0 +1,107 @@ +/* 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/core/common/cookie_settings_base.h" + +#include "base/containers/flat_map.h" +#include "base/no_destructor.h" +#include "base/optional.h" +#include "net/base/registry_controlled_domains/registry_controlled_domain.h" +#include "components/content_settings/core/common/content_settings.h" +#include "components/content_settings/core/common/content_settings_pattern.h" +#include "url/gurl.h" +#include "url/origin.h" + +namespace content_settings { + +namespace { + +constexpr char kWp[] = "https://[*.]wp.com/*"; +constexpr char kWordpress[] = "https://[*.]wordpress.com/*"; +constexpr char kPlaystation[] = "https://[*.]playstation.com/*"; +constexpr char kSonyentertainmentnetwork[] = + "https://[*.]sonyentertainmentnetwork.com/*"; + +bool BraveIsAllowedThirdParty( + const GURL& url, + const GURL& site_for_cookies, + const base::Optional& top_frame_origin) { + static const base::NoDestructor< + // url -> first_party_url allow map + std::vector>> entity_list({ + { + ContentSettingsPattern::FromString(kWp), + ContentSettingsPattern::FromString(kWordpress) + }, + { + ContentSettingsPattern::FromString(kWordpress), + ContentSettingsPattern::FromString(kWp) + }, + { + ContentSettingsPattern::FromString(kPlaystation), + ContentSettingsPattern::FromString(kSonyentertainmentnetwork)}, + { + ContentSettingsPattern::FromString(kSonyentertainmentnetwork), + ContentSettingsPattern::FromString(kPlaystation) + }, + }); + + GURL first_party_url = site_for_cookies; + + if (!first_party_url.is_valid() && top_frame_origin) + first_party_url = top_frame_origin->GetURL(); + + if (net::registry_controlled_domains::GetDomainAndRegistry( + url, + net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES) == + net::registry_controlled_domains::GetDomainAndRegistry( + first_party_url, + net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES)) + return true; + + for (auto i = entity_list->begin(); + i != entity_list->end(); + ++i) { + if (i->first.Matches(url) && i->second.Matches(first_party_url)) + return true; + } + + return false; +} + +} // namespace + +bool CookieSettingsBase::IsCookieAccessAllowed( + const GURL& url, const GURL& first_party_url) const { + return IsCookieAccessAllowed(url, first_party_url, base::nullopt); +} + +bool CookieSettingsBase::IsCookieAccessAllowed( + 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); + + // content settings should always override any defaults + if (!IsAllowed(setting)) + return false; + + if (BraveIsAllowedThirdParty(url, site_for_cookies, top_frame_origin)) + return true; + + return IsChromiumCookieAccessAllowed(url, site_for_cookies, top_frame_origin); +} + +} // namespce content_settings + +#define IsCookieAccessAllowed IsChromiumCookieAccessAllowed +#include "../../../../../../components/content_settings/core/common/cookie_settings_base.cc" // NOLINT +#undef IsCookieAccessAllowed 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 new file mode 100644 index 000000000000..0d384515c5ce --- /dev/null +++ b/chromium_src/components/content_settings/core/common/cookie_settings_base.h @@ -0,0 +1,22 @@ +/* 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_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, \ + const base::Optional& top_frame_origin) const; + +#include "../../../../../../components/content_settings/core/common/cookie_settings_base.h" + +#undef BRAVE_COOKIE_SETTINGS_BASE_H + +#endif // BRAVE_CHROMIUM_SRC_COMPONENTS_CONTENT_SETTINGS_CORE_COMMON_COOKIE_SETTINGS_BASE_H_ diff --git a/components/content_settings/core/browser/brave_content_settings_pref_provider.cc b/components/content_settings/core/browser/brave_content_settings_pref_provider.cc index bfc694576d0e..1dc8b24d698e 100644 --- a/components/content_settings/core/browser/brave_content_settings_pref_provider.cc +++ b/components/content_settings/core/browser/brave_content_settings_pref_provider.cc @@ -313,40 +313,8 @@ void BravePrefProvider::UpdateCookieRules(ContentSettingsType content_type, rules.push_back(CloneRule(rule)); brave_cookie_rules_[incognito].push_back(CloneRule(rule)); } - - // Add 3p cookie exception to handle an oddity in how Wordpress implements - // first party widgets on their site. Wordpress implements it'd - // "notifications" sidebar with the following pattern, which results in - // first party cookies being blocked, because of the intermediate - // api.wp.com frame. - // - // https://yoursite.wordpress.com - //