Skip to content

Commit

Permalink
Prevent storage partitioning bypass with a trial when Shields active.
Browse files Browse the repository at this point in the history
  • Loading branch information
goodov committed Jan 9, 2025
1 parent 1dcceaa commit ae964a8
Show file tree
Hide file tree
Showing 7 changed files with 184 additions and 2 deletions.
22 changes: 22 additions & 0 deletions browser/brave_content_browser_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@
#include "chrome/browser/chrome_browser_interface_binders.h"
#include "chrome/browser/chrome_browser_main.h"
#include "chrome/browser/chrome_content_browser_client.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/profiles/profile_io_data.h"
Expand Down Expand Up @@ -689,6 +690,27 @@ BraveContentBrowserClient::GetEphemeralStorageToken(
return es_tab_helper->GetEphemeralStorageToken(origin);
}

bool BraveContentBrowserClient::CanThirdPartyStoragePartitioningBeDisabled(
content::BrowserContext* browser_context,
const url::Origin& origin) {
auto* host_content_settings_map =
HostContentSettingsMapFactory::GetForProfile(browser_context);
if (!host_content_settings_map) {
return false;
}
auto cookie_settings = CookieSettingsFactory::GetForProfile(
Profile::FromBrowserContext(browser_context));
if (!cookie_settings) {
return false;
}
const auto url = origin.GetURL();
return !brave_shields::GetBraveShieldsEnabled(host_content_settings_map,
url) ||
brave_shields::GetCookieControlType(host_content_settings_map,
cookie_settings.get(), url) ==
brave_shields::ControlType::ALLOW;
}

bool BraveContentBrowserClient::AllowWorkerFingerprinting(
const GURL& url,
content::BrowserContext* browser_context) {
Expand Down
4 changes: 4 additions & 0 deletions browser/brave_content_browser_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ class BraveContentBrowserClient : public ChromeContentBrowserClient {
content::RenderFrameHost* render_frame_host,
const url::Origin& origin) override;

bool CanThirdPartyStoragePartitioningBeDisabled(
content::BrowserContext* browser_context,
const url::Origin& origin) override;

bool AllowWorkerFingerprinting(
const GURL& url,
content::BrowserContext* browser_context) override;
Expand Down
124 changes: 124 additions & 0 deletions browser/ephemeral_storage/ephemeral_storage_browsertest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,15 @@
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_enums.h"
#include "chrome/test/base/chrome_test_utils.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/prefs/pref_service.h"
#include "content/public/browser/browsing_data_remover.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/content_paths.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test.h"
Expand Down Expand Up @@ -1277,3 +1280,124 @@ IN_PROC_BROWSER_TEST_F(
EXPECT_EQ("", values_after.iframe_1.cookies);
EXPECT_EQ("", values_after.iframe_2.cookies);
}

class EphemeralStorageWithDisableThirdPartyStoragePartitioningBrowserTest
: public EphemeralStorageBrowserTest,
public content::WebContentsObserver,
public testing::WithParamInterface<bool> {
public:
EphemeralStorageWithDisableThirdPartyStoragePartitioningBrowserTest() {}

void ReadyToCommitNavigation(
content::NavigationHandle* navigation_handle) override {
if (!navigation_handle->IsInPrimaryMainFrame()) {
return;
}

blink::RuntimeFeatureStateContext& context =
navigation_handle->GetMutableRuntimeFeatureStateContext();
context.SetDisableThirdPartyStoragePartitioning2Enabled(GetParam());
}
};

IN_PROC_BROWSER_TEST_P(
EphemeralStorageWithDisableThirdPartyStoragePartitioningBrowserTest,
StorageIsPartitionedWithShieldsEnabled) {
auto* web_contents = chrome_test_utils::GetActiveWebContents(this);
Observe(web_contents);
ASSERT_TRUE(
brave_shields::GetBraveShieldsEnabled(content_settings(), GURL()));

ASSERT_TRUE(
ui_test_utils::NavigateToURL(browser(), a_site_ephemeral_storage_url_));

// The page this tab is loaded via a.com and has two b.com third-party
// iframes. The third-party iframes should be partitioned.
SetValuesInFrames(web_contents, "a.com", "from=a.com");
ValuesFromFrames third_party_values = GetValuesFromFrames(web_contents);
EXPECT_EQ("a.com", third_party_values.main_frame.local_storage);
EXPECT_EQ("a.com", third_party_values.iframe_1.local_storage);
EXPECT_EQ("a.com", third_party_values.iframe_2.local_storage);

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

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

ASSERT_TRUE(
ui_test_utils::NavigateToURL(browser(), b_site_ephemeral_storage_url_));

// The storage in the first-party iframes should reflect empty values not
// altered by a.com site.
ValuesFromFrames first_party_values = GetValuesFromFrames(web_contents);
ExpectValuesFromFramesAreEmpty(FROM_HERE, first_party_values);
}

IN_PROC_BROWSER_TEST_P(
EphemeralStorageWithDisableThirdPartyStoragePartitioningBrowserTest,
StorageIsPartitionedWithShieldsDisabled) {
auto* web_contents = chrome_test_utils::GetActiveWebContents(this);
Observe(chrome_test_utils::GetActiveWebContents(this));
brave_shields::SetBraveShieldsEnabled(content_settings(), false,
a_site_ephemeral_storage_url_);
brave_shields::SetBraveShieldsEnabled(content_settings(), false,
b_site_ephemeral_storage_url_);
brave_shields::SetBraveShieldsEnabled(content_settings(), false,
c_site_ephemeral_storage_url_);

ASSERT_TRUE(
ui_test_utils::NavigateToURL(browser(), a_site_ephemeral_storage_url_));

// The page this tab is loaded via a.com and has two b.com third-party
// iframes. The third-party iframes should be partitioned.
SetValuesInFrames(web_contents, "a.com", "from=a.com");
ValuesFromFrames third_party_values = GetValuesFromFrames(web_contents);
EXPECT_EQ("a.com", third_party_values.main_frame.local_storage);
EXPECT_EQ("a.com", third_party_values.iframe_1.local_storage);
EXPECT_EQ("a.com", third_party_values.iframe_2.local_storage);

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

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

ASSERT_TRUE(
ui_test_utils::NavigateToURL(browser(), b_site_ephemeral_storage_url_));

ValuesFromFrames first_party_values = GetValuesFromFrames(web_contents);
if (GetParam()) {
// If origin trial is enabled, the storage should not be partitioned.
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);
} else {
// If origin trial is disabled, the storage should be partitioned.
EXPECT_EQ(nullptr, 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(nullptr, 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);
}

// Cookies are not partitioned if shields are disabled.
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);
}

INSTANTIATE_TEST_SUITE_P(
,
EphemeralStorageWithDisableThirdPartyStoragePartitioningBrowserTest,
testing::Bool());
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,18 @@
return *ephemeral_storage_token; \
}

#define BRAVE_RENDER_FRAME_HOST_IMPL_IS_THIRD_PARTY_STORAGE_PARTITIONING_ENABLED_CHECK_IF_CAN_BE_DISABLED \
if (GetContentClient() \
->browser() \
->CanThirdPartyStoragePartitioningBeDisabled( \
GetBrowserContext(), \
main_frame_for_storage_partitioning->GetLastCommittedOrigin()))

#include "src/content/browser/renderer_host/render_frame_host_impl.cc"

#undef BRAVE_RENDER_FRAME_HOST_IMPL_COMPUTE_ISOLATION_INFO_INTERNAL
#undef BRAVE_RENDER_FRAME_HOST_IMPL_COMPUTE_NONCE
#undef BRAVE_RENDER_FRAME_HOST_IMPL_IS_THIRD_PARTY_STORAGE_PARTITIONING_ENABLED_CHECK_IF_CAN_BE_DISABLED

namespace content {

Expand Down
6 changes: 6 additions & 0 deletions chromium_src/content/public/browser/content_browser_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ ContentBrowserClient::GetEphemeralStorageToken(
return std::nullopt;
}

bool ContentBrowserClient::CanThirdPartyStoragePartitioningBeDisabled(
BrowserContext* browser_context,
const url::Origin& origin) {
return false;
}

brave_shields::mojom::ShieldsSettingsPtr
ContentBrowserClient::WorkerGetBraveShieldSettings(
const GURL& url,
Expand Down
2 changes: 2 additions & 0 deletions chromium_src/content/public/browser/content_browser_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
const GURL& url); \
virtual std::optional<base::UnguessableToken> GetEphemeralStorageToken( \
RenderFrameHost* render_frame_host, const url::Origin& origin); \
virtual bool CanThirdPartyStoragePartitioningBeDisabled( \
BrowserContext* browser_context, const url::Origin& origin); \
virtual bool AllowWorkerFingerprinting(const GURL& url, \
BrowserContext* browser_context); \
virtual brave_shields::mojom::ShieldsSettingsPtr \
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index f58b9b0333e01f95ecf1b1d3fd3e273b675705cc..0d8c54fa8dcf8052f9c6d6a28cd5d0395688ec1e 100644
index f58b9b0333e01f95ecf1b1d3fd3e273b675705cc..e14627f84f7dab5f368e36dbc30d8fbeb87409df 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -4820,6 +4820,7 @@ net::IsolationInfo RenderFrameHostImpl::ComputeIsolationInfoInternal(
Expand All @@ -18,7 +18,23 @@ index f58b9b0333e01f95ecf1b1d3fd3e273b675705cc..0d8c54fa8dcf8052f9c6d6a28cd5d039
// If it's a credentialless frame tree, use its nonce even if it's within a
// fenced frame tree to maintain the guarantee that a credentialless frame
// tree has a unique nonce.
@@ -9236,6 +9238,7 @@ void RenderFrameHostImpl::CreateNewWindow(
@@ -4872,6 +4874,7 @@ bool RenderFrameHostImpl::IsThirdPartyStoragePartitioningEnabled(
// current value of net::features::ThirdPartyStoragePartitioning.
if (rfs_document_data_for_storage_key->runtime_feature_state_read_context()
.IsDisableThirdPartyStoragePartitioning2Enabled()) {
+ BRAVE_RENDER_FRAME_HOST_IMPL_IS_THIRD_PARTY_STORAGE_PARTITIONING_ENABLED_CHECK_IF_CAN_BE_DISABLED
return false;
}
// Compile the list of third-party origins we need to check in addition to
@@ -4889,6 +4892,7 @@ bool RenderFrameHostImpl::IsThirdPartyStoragePartitioningEnabled(
if (rfs_document_data_for_storage_key->runtime_feature_state_read_context()
.IsDisableThirdPartyStoragePartitioning2EnabledForThirdParty(
third_party_origins)) {
+ BRAVE_RENDER_FRAME_HOST_IMPL_IS_THIRD_PARTY_STORAGE_PARTITIONING_ENABLED_CHECK_IF_CAN_BE_DISABLED
return false;
}
} else {
@@ -9236,6 +9240,7 @@ void RenderFrameHostImpl::CreateNewWindow(
dom_storage_context, params->session_storage_namespace_id);
}

Expand Down

0 comments on commit ae964a8

Please sign in to comment.