Skip to content

Commit

Permalink
allow first party iframes embedded in 3rd-party origins plus exceptio…
Browse files Browse the repository at this point in the history
…ns for wp/wordpress and playstation/sonyentertainmentnetwork

fix brave/brave-browser#8629
fix brave/brave-browser#9564
  • Loading branch information
bridiver committed May 6, 2020
1 parent ba50382 commit 8a70586
Show file tree
Hide file tree
Showing 5 changed files with 185 additions and 36 deletions.
44 changes: 42 additions & 2 deletions browser/net/brave_network_delegate_browsertest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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()
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
@@ -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<url::Origin>& top_frame_origin) {
static const base::NoDestructor<
// url -> first_party_url allow map
std::vector<std::pair<ContentSettingsPattern,
ContentSettingsPattern>>> 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<url::Origin>& 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
Original file line number Diff line number Diff line change
@@ -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<url::Origin>& 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_
Original file line number Diff line number Diff line change
Expand Up @@ -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
// <iframe src="//widgets.wp.com"> <-- no storage
// <iframe src="//public-api.wordpress.com"> <-- ALSO no storage, despite
// being eTLD+1 equal with
// top level frame.
//
// See https://github.com/brave/brave-browser/issues/9064 and
// https://github.com/brave/brave-browser/issues/9105 (this approach is
// a stop gap solution until #9105 is solved).
const auto wordpress_host_pattern = ContentSettingsPattern::FromString(
"https://[*.]wordpress.com/*");
const auto wp_host_pattern = ContentSettingsPattern::FromString(
"https://[*.]wp.com/*");

auto widgets_wp_com_rule = Rule(
wordpress_host_pattern,
wp_host_pattern,
ContentSettingToValue(CONTENT_SETTING_ALLOW)->Clone());
rules.push_back(CloneRule(widgets_wp_com_rule));
brave_cookie_rules_[incognito].push_back(CloneRule(widgets_wp_com_rule));

auto wp_com_rule = Rule(
wp_host_pattern,
wordpress_host_pattern,
ContentSettingToValue(CONTENT_SETTING_ALLOW)->Clone());
rules.push_back(CloneRule(wp_com_rule));
brave_cookie_rules_[incognito].push_back(CloneRule(wp_com_rule));
// non-pref based exceptions should go in the cookie_settings_base.cc
// chromium_src override

// add chromium cookies
auto chromium_cookies_iterator = PrefProvider::GetRuleIterator(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
diff --git a/components/content_settings/core/common/cookie_settings_base.h b/components/content_settings/core/common/cookie_settings_base.h
index fb41bd86314482bb8f9116e4da454c7913b74158..987040b59709fc7cca7a28ea75a880fc5bc6171a 100644
--- a/components/content_settings/core/common/cookie_settings_base.h
+++ b/components/content_settings/core/common/cookie_settings_base.h
@@ -169,6 +169,7 @@ class CookieSettingsBase {
// Determines whether |setting| is a valid content setting for legacy cookie
// access.
static bool IsValidSettingForLegacyAccess(ContentSetting setting);
+ BRAVE_COOKIE_SETTINGS_BASE_H

private:
virtual void GetCookieSettingInternal(

0 comments on commit 8a70586

Please sign in to comment.