Skip to content

Commit

Permalink
Add ephemeral storage enabler to domain block throttler.
Browse files Browse the repository at this point in the history
  • Loading branch information
goodov committed Oct 29, 2021
1 parent 466b2da commit 2678787
Show file tree
Hide file tree
Showing 22 changed files with 673 additions and 92 deletions.
2 changes: 2 additions & 0 deletions browser/brave_content_browser_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "brave/browser/brave_browser_process.h"
#include "brave/browser/brave_shields/brave_shields_web_contents_observer.h"
#include "brave/browser/debounce/debounce_service_factory.h"
#include "brave/browser/ephemeral_storage/ephemeral_storage_service_factory.h"
#include "brave/browser/ethereum_remote_client/buildflags/buildflags.h"
#include "brave/browser/net/brave_proxying_url_loader_factory.h"
#include "brave/browser/net/brave_proxying_web_socket.h"
Expand Down Expand Up @@ -816,6 +817,7 @@ BraveContentBrowserClient::CreateThrottlesForNavigation(
brave_shields::DomainBlockNavigationThrottle::MaybeCreateThrottleFor(
handle, g_brave_browser_process->ad_block_service(),
g_brave_browser_process->ad_block_custom_filters_service(),
EphemeralStorageServiceFactory::GetForContext(context),
HostContentSettingsMapFactory::GetForProfile(
Profile::FromBrowserContext(context)),
g_browser_process->GetApplicationLocale()))
Expand Down
28 changes: 0 additions & 28 deletions browser/ephemeral_storage/BUILD.gn

This file was deleted.

59 changes: 0 additions & 59 deletions browser/ephemeral_storage/ephemeral_storage_1p_browsertest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
#include "brave/browser/ephemeral_storage/ephemeral_storage_browsertest.h"

#include "base/strings/strcat.h"
#include "base/test/bind.h"
#include "brave/components/brave_shields/browser/brave_shields_util.h"
#include "chrome/browser/content_settings/cookie_settings_factory.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
Expand All @@ -32,64 +31,6 @@ class EphemeralStorage1pBrowserTest : public EphemeralStorageBrowserTest {
}
~EphemeralStorage1pBrowserTest() override {}

void SetCookieSetting(const GURL& url, ContentSetting content_setting) {
auto* host_content_settings_map =
HostContentSettingsMapFactory::GetForProfile(browser()->profile());
host_content_settings_map->SetContentSettingCustomScope(
ContentSettingsPattern::FromString(
base::StrCat({"[*.]", url.host_piece(), ":*"})),
ContentSettingsPattern::Wildcard(), ContentSettingsType::COOKIES,
content_setting);
}

// Helper to load easy-to-use Indexed DB API.
void LoadIndexedDbHelper(RenderFrameHost* host) {
const char kLoadIndexMinScript[] =
"new Promise((resolve) => {"
" const script = document.createElement('script');"
" script.onload = () => {"
" resolve(true);"
" };"
" script.onerror = () => {"
" resolve(false);"
" };"
" script.src = '/ephemeral-storage/static/js/libs/index-min.js';"
" document.body.appendChild(script);"
"});";

ASSERT_EQ(true, content::EvalJs(host, kLoadIndexMinScript));
}

bool SetIDBValue(RenderFrameHost* host) {
LoadIndexedDbHelper(host);
content::EvalJsResult eval_js_result = content::EvalJs(
host, "(async () => { await window.idbKeyval.set('a', 'a'); })()");
return eval_js_result.error.empty();
}

HostContentSettingsMap* content_settings() {
return HostContentSettingsMapFactory::GetForProfile(browser()->profile());
}

network::mojom::CookieManager* CookieManager() {
return browser()
->profile()
->GetDefaultStoragePartition()
->GetCookieManagerForBrowserProcess();
}

std::vector<net::CanonicalCookie> GetAllCookies() {
base::RunLoop run_loop;
std::vector<net::CanonicalCookie> cookies_out;
CookieManager()->GetAllCookies(base::BindLambdaForTesting(
[&](const std::vector<net::CanonicalCookie>& cookies) {
cookies_out = cookies;
run_loop.Quit();
}));
run_loop.Run();
return cookies_out;
}

private:
base::test::ScopedFeatureList scoped_feature_list_;
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
/* Copyright (c) 2021 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 "brave/browser/ephemeral_storage/ephemeral_storage_browsertest.h"

#include "base/test/bind.h"
#include "base/test/thread_test_helper.h"
#include "brave/browser/brave_browser_process.h"
#include "brave/components/brave_component_updater/browser/local_data_files_service.h"
#include "brave/components/brave_shields/browser/ad_block_service.h"
#include "brave/components/brave_shields/browser/brave_shields_util.h"
#include "chrome/browser/interstitials/security_interstitial_page_test_utils.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/test_navigation_observer.h"
#include "net/base/features.h"
#include "services/network/public/mojom/cookie_manager.mojom.h"

using content::RenderFrameHost;
using content::WebContents;

class EphemeralStorage1pDomainBlockBrowserTest
: public EphemeralStorageBrowserTest {
public:
EphemeralStorage1pDomainBlockBrowserTest() {
scoped_feature_list_.InitAndEnableFeature(
net::features::kBraveFirstPartyEphemeralStorage);
}
~EphemeralStorage1pDomainBlockBrowserTest() override {}

void SetUpOnMainThread() override {
EphemeralStorageBrowserTest::SetUpOnMainThread();
}

void UpdateAdBlockInstanceWithRules(const std::string& rules,
const std::string& resources = "") {
brave_shields::AdBlockService* ad_block_service =
g_brave_browser_process->ad_block_service();
ad_block_service->GetTaskRunner()->PostTask(
FROM_HERE,
base::BindOnce(&brave_shields::AdBlockService::ResetForTest,
base::Unretained(ad_block_service), rules, resources));
WaitForAdBlockServiceThreads();
}

void WaitForAdBlockServiceThreads() {
scoped_refptr<base::ThreadTestHelper> tr_helper(new base::ThreadTestHelper(
g_brave_browser_process->local_data_files_service()->GetTaskRunner()));
ASSERT_TRUE(tr_helper->Run());
}

void BlockDomainByURL(const GURL& url) {
UpdateAdBlockInstanceWithRules("||" + url.host() + "^");
}

bool IsShowingInterstitial(WebContents* web_contents) {
return chrome_browser_interstitials::IsShowingInterstitial(web_contents);
}

void Click(WebContents* web_contents, const std::string& id) {
content::RenderFrameHost* frame = web_contents->GetMainFrame();
frame->ExecuteJavaScriptForTests(
base::ASCIIToUTF16("document.getElementById('" + id + "').click();\n"),
base::NullCallback());
}

void ClickAndWaitForNavigation(WebContents* web_contents,
const std::string& id) {
content::TestNavigationObserver observer(
web_contents, 1, content::MessageLoopRunner::QuitMode::DEFERRED);
Click(web_contents, id);
observer.Wait();
}

WebContents* NavigateToBlockedDomain() {
brave_shields::SetCosmeticFilteringControlType(
content_settings(), brave_shields::ControlType::BLOCK,
a_site_ephemeral_storage_url_);
BlockDomainByURL(a_site_ephemeral_storage_url_);

WebContents* first_party_tab =
LoadURLInNewTab(a_site_ephemeral_storage_url_);
EXPECT_TRUE(IsShowingInterstitial(first_party_tab));
Click(first_party_tab, "dont-warn-again-checkbox");
ClickAndWaitForNavigation(first_party_tab, "primary-button");

// We set a value in the page where all the frames are first-party.
SetValuesInFrames(first_party_tab, "a.com", "from=a.com");

{
ValuesFromFrames first_party_values =
GetValuesFromFrames(first_party_tab);
EXPECT_EQ("a.com", first_party_values.main_frame.local_storage);
EXPECT_EQ("a.com", first_party_values.iframe_1.local_storage);
EXPECT_EQ("a.com", first_party_values.iframe_2.local_storage);

EXPECT_EQ("a.com", first_party_values.main_frame.session_storage);
EXPECT_EQ("a.com", first_party_values.iframe_1.session_storage);
EXPECT_EQ("a.com", first_party_values.iframe_2.session_storage);

EXPECT_EQ("from=a.com", first_party_values.main_frame.cookies);
EXPECT_EQ("from=a.com", first_party_values.iframe_1.cookies);
EXPECT_EQ("from=a.com", first_party_values.iframe_2.cookies);
}

return first_party_tab;
}

void NavigateToBlockedDomainAndExpectEphemeralEnabled() {
WebContents* first_party_tab = NavigateToBlockedDomain();

// After keepalive values should be cleared.
ASSERT_TRUE(
ui_test_utils::NavigateToURL(browser(), b_site_ephemeral_storage_url_));
WaitForCleanupAfterKeepAlive();
ASSERT_TRUE(
ui_test_utils::NavigateToURL(browser(), a_site_ephemeral_storage_url_));

ExpectValuesFromFramesAreEmpty(FROM_HERE,
GetValuesFromFrames(first_party_tab));
}

void NavigateToBlockedDomainAndExpectNotEphemeral() {
WebContents* first_party_tab = NavigateToBlockedDomain();

// After keepalive main frame values should not be cleared.
ASSERT_TRUE(
ui_test_utils::NavigateToURL(browser(), b_site_ephemeral_storage_url_));
WaitForCleanupAfterKeepAlive();
ASSERT_TRUE(
ui_test_utils::NavigateToURL(browser(), a_site_ephemeral_storage_url_));

{
ValuesFromFrames first_party_values =
GetValuesFromFrames(first_party_tab);
EXPECT_EQ("a.com", first_party_values.main_frame.local_storage);
EXPECT_EQ(nullptr, first_party_values.iframe_1.local_storage);
EXPECT_EQ(nullptr, first_party_values.iframe_2.local_storage);

EXPECT_EQ("a.com", first_party_values.main_frame.session_storage);
EXPECT_EQ(nullptr, first_party_values.iframe_1.session_storage);
EXPECT_EQ(nullptr, first_party_values.iframe_2.session_storage);

EXPECT_EQ("from=a.com", first_party_values.main_frame.cookies);
EXPECT_EQ("", first_party_values.iframe_1.cookies);
EXPECT_EQ("", first_party_values.iframe_2.cookies);
}
}

private:
base::test::ScopedFeatureList scoped_feature_list_;
};

IN_PROC_BROWSER_TEST_F(
EphemeralStorage1pDomainBlockBrowserTest,
FirstPartyEphemeralIsEnabledAfterIntersisitalProcessing) {
brave_shields::SetCosmeticFilteringControlType(
content_settings(), brave_shields::ControlType::BLOCK,
a_site_ephemeral_storage_url_);
BlockDomainByURL(a_site_ephemeral_storage_url_);

NavigateToBlockedDomainAndExpectEphemeralEnabled();
}

IN_PROC_BROWSER_TEST_F(EphemeralStorage1pDomainBlockBrowserTest,
FirstPartyEphemeralIsNotEnabledIfCookiesStored) {
ASSERT_TRUE(content::SetCookie(browser()->profile(),
a_site_ephemeral_storage_url_,
"from=a.com;SameSite=None;Secure"));

NavigateToBlockedDomainAndExpectNotEphemeral();
}

IN_PROC_BROWSER_TEST_F(
EphemeralStorage1pDomainBlockBrowserTest,
FirstPartyEphemeralIsNotEnabledIfLocalStorageDataStored) {
// Store local storage value in a.com.
WebContents* first_party_tab = LoadURLInNewTab(a_site_ephemeral_storage_url_);
SetStorageValueInFrame(first_party_tab->GetMainFrame(), "a.com",
StorageType::Local);
// Navigate away to b.com.
ASSERT_TRUE(
ui_test_utils::NavigateToURL(browser(), b_site_ephemeral_storage_url_));

NavigateToBlockedDomainAndExpectNotEphemeral();
}
64 changes: 64 additions & 0 deletions browser/ephemeral_storage/ephemeral_storage_browsertest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,20 @@
#include "base/path_service.h"
#include "base/strings/strcat.h"
#include "base/strings/stringprintf.h"
#include "base/test/bind.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/time/time.h"
#include "brave/browser/ephemeral_storage/ephemeral_storage_tab_helper.h"
#include "brave/common/brave_paths.h"
#include "brave/components/brave_shields/browser/brave_shields_util.h"
#include "brave/components/brave_shields/common/brave_shield_constants.h"
#include "chrome/browser/content_settings/cookie_settings_factory.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/content_settings/core/browser/cookie_settings.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/network_session_configurator/common/network_switches.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/notification_types.h"
Expand Down Expand Up @@ -304,6 +308,66 @@ content::EvalJsResult EphemeralStorageBrowserTest::GetBroadcastMessage(
return content::EvalJs(frame, "self.bc_message");
}

void EphemeralStorageBrowserTest::SetCookieSetting(
const GURL& url,
ContentSetting content_setting) {
auto* host_content_settings_map =
HostContentSettingsMapFactory::GetForProfile(browser()->profile());
host_content_settings_map->SetContentSettingCustomScope(
ContentSettingsPattern::FromString(
base::StrCat({"[*.]", url.host_piece(), ":*"})),
ContentSettingsPattern::Wildcard(), ContentSettingsType::COOKIES,
content_setting);
}

// Helper to load easy-to-use Indexed DB API.
void EphemeralStorageBrowserTest::LoadIndexedDbHelper(RenderFrameHost* host) {
const char kLoadIndexMinScript[] =
"new Promise((resolve) => {"
" const script = document.createElement('script');"
" script.onload = () => {"
" resolve(true);"
" };"
" script.onerror = () => {"
" resolve(false);"
" };"
" script.src = '/ephemeral-storage/static/js/libs/index-min.js';"
" document.body.appendChild(script);"
"});";

ASSERT_EQ(true, content::EvalJs(host, kLoadIndexMinScript));
}

bool EphemeralStorageBrowserTest::SetIDBValue(RenderFrameHost* host) {
LoadIndexedDbHelper(host);
content::EvalJsResult eval_js_result = content::EvalJs(
host, "(async () => { await window.idbKeyval.set('a', 'a'); })()");
return eval_js_result.error.empty();
}

HostContentSettingsMap* EphemeralStorageBrowserTest::content_settings() {
return HostContentSettingsMapFactory::GetForProfile(browser()->profile());
}

network::mojom::CookieManager* EphemeralStorageBrowserTest::CookieManager() {
return browser()
->profile()
->GetDefaultStoragePartition()
->GetCookieManagerForBrowserProcess();
}

std::vector<net::CanonicalCookie> EphemeralStorageBrowserTest::GetAllCookies() {
base::RunLoop run_loop;
std::vector<net::CanonicalCookie> cookies_out;
CookieManager()->GetAllCookies(base::BindLambdaForTesting(
[&](const std::vector<net::CanonicalCookie>& cookies) {
cookies_out = cookies;
run_loop.Quit();
}));
run_loop.Run();
return cookies_out;
}

IN_PROC_BROWSER_TEST_F(EphemeralStorageBrowserTest, StorageIsPartitioned) {
WebContents* first_party_tab = LoadURLInNewTab(b_site_ephemeral_storage_url_);
WebContents* site_a_tab1 =
Expand Down
Loading

0 comments on commit 2678787

Please sign in to comment.