0

[Privacy Sandbox] Chrome client layer implementation of local

unpartitioned data access attestation check.

Implement the browser client layer check of the new attestation API.
Apply this check for shared storage get.

Browser tests for testing shared storage get with respect to the new
attestation check is added in:
chrome/browser/storage/shared_storage_browsertest.cc.

Update other existing tests to work with this check.

Please note other than the attestation, the local unpartitioned data
access is also gated on 3pc setting. See crrev.com/c/5860019.

Bug: 361375807
Change-Id: I338bb9fa756b9e2b793f3bf4a491281cd41409f6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5854085
Reviewed-by: Avi Drissman <avi@chromium.org>
Commit-Queue: Xiaochen Zhou <xiaochenzh@chromium.org>
Reviewed-by: Shivani Sharma <shivanisha@chromium.org>
Reviewed-by: Eric Seckler <eseckler@chromium.org>
Reviewed-by: Cammie Smith Barnes <cammie@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1370560}
This commit is contained in:
Xiaochen Zhou
2024-10-18 14:14:03 +00:00
committed by Chromium LUCI CQ
parent c8bf3beec3
commit e653034d14
15 changed files with 466 additions and 13 deletions

@@ -3632,6 +3632,27 @@ bool ChromeContentBrowserClient::IsSharedStorageSelectURLAllowed(
out_block_is_site_setting_specific);
}
bool ChromeContentBrowserClient::
IsFencedFramesLocalUnpartitionedDataAccessAllowed(
content::BrowserContext* browser_context,
content::RenderFrameHost* rfh,
const url::Origin& top_frame_origin,
const url::Origin& accessing_origin) {
Profile* profile = Profile::FromBrowserContext(browser_context);
auto* privacy_sandbox_settings =
PrivacySandboxSettingsFactory::GetForProfile(profile);
DCHECK(privacy_sandbox_settings);
bool allowed =
privacy_sandbox_settings->IsLocalUnpartitionedDataAccessAllowed(
top_frame_origin, accessing_origin, rfh);
if (rfh) {
content_settings::PageSpecificContentSettings::BrowsingDataAccessed(
rfh, blink::StorageKey::CreateFirstParty(accessing_origin),
BrowsingDataModel::StorageType::kSharedStorage, !allowed);
}
return allowed;
}
bool ChromeContentBrowserClient::IsPrivateAggregationAllowed(
content::BrowserContext* browser_context,
const url::Origin& top_frame_origin,

@@ -372,6 +372,7 @@ class ChromeContentBrowserClient : public content::ContentBrowserClient {
content::RenderFrameHost* rfh,
const url::Origin& context_origin,
const url::Origin& reporting_origin) override;
// TODO(crbug.com/369436599): Remove the default arguments in virtual methods.
bool IsSharedStorageAllowed(
content::BrowserContext* browser_context,
content::RenderFrameHost* rfh,
@@ -385,6 +386,11 @@ class ChromeContentBrowserClient : public content::ContentBrowserClient {
const url::Origin& accessing_origin,
std::string* out_debug_message = nullptr,
bool* out_block_is_site_setting_specific = nullptr) override;
bool IsFencedFramesLocalUnpartitionedDataAccessAllowed(
content::BrowserContext* browser_context,
content::RenderFrameHost* rfh,
const url::Origin& top_frame_origin,
const url::Origin& accessing_origin) override;
bool IsPrivateAggregationAllowed(
content::BrowserContext* browser_context,
const url::Origin& top_frame_origin,

@@ -56,6 +56,7 @@
#include "content/public/test/back_forward_cache_util.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/fenced_frame_test_util.h"
#include "content/public/test/shared_storage_test_utils.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_select_url_fenced_frame_config_observer.h"
@@ -99,6 +100,7 @@ const auto& ClearOperation =
constexpr char kMainHost[] = "a.test";
constexpr char kSimplePagePath[] = "/simple.html";
constexpr char kFencedFramePagePath[] = "/fenced_frames/title1.html";
constexpr char kTitle1Path[] = "/title1.html";
constexpr char kCrossOriginHost[] = "b.test";
constexpr char kThirdOriginHost[] = "c.test";
@@ -122,6 +124,8 @@ constexpr char kTimingDocumentAppendHistogram[] =
"Storage.SharedStorage.Document.Timing.Append";
constexpr char kTimingDocumentSetHistogram[] =
"Storage.SharedStorage.Document.Timing.Set";
constexpr char kTimingDocumentGetHistogram[] =
"Storage.SharedStorage.Document.Timing.Get";
constexpr char kTimingDocumentDeleteHistogram[] =
"Storage.SharedStorage.Document.Timing.Delete";
constexpr char kTimingDocumentClearHistogram[] =
@@ -155,6 +159,14 @@ constexpr char
"PrivacySandbox.PrivateAggregation.Host."
"TimeToGenerateReportRequestWithContextId";
constexpr char
kFencedFrameLocalUnpartitionedDataAccessAttestationErrorPrefix[] =
"Attestation check for local unpartitioned data access on";
constexpr char
kFencedFrameLocalUnpartitionedDataAccessDisabledBy3pcSettingError[] =
"Fenced frame local unpartitioned data access is disabled because all "
"third-party cookies are blocked.";
const double kBudgetAllowed = 5.0;
// In order to cut back on the total number of tests run, we deliberately only
@@ -195,6 +207,20 @@ MakeFilter(std::vector<std::string> possible_last_messages) {
std::move(possible_last_messages));
}
std::string GetFencedFrameLocalUnpartitionedDataAccessDisabledMessage() {
return base::StrCat(
{"a JavaScript error: \"OperationError: ",
content::GetFencedFrameLocalUnpartitionedDataAccessDisabledMessage()});
}
std::string
GetFencedFrameLocalUnpartitionedDataAccessWithoutRevokeNetworkMessage() {
return base::StrCat(
{"a JavaScript error: \"OperationError: ",
content::
GetFencedFrameLocalUnpartitionedDataAccessWithoutRevokeNetworkMessage()});
}
std::string GetSharedStorageDisabledErrorMessage() {
return base::StrCat({"a JavaScript error: \"OperationError: ",
content::GetSharedStorageDisabledMessage()});
@@ -735,7 +761,7 @@ class SharedStorageChromeBrowserTestBase : public PlatformBrowserTest {
}
virtual bool EnableDebugMessages() const { return false; }
bool SuccessExpected() {
bool SuccessExpected() const {
return GetEnforcementAndEnrollmentStatus() !=
EnforcementAndEnrollmentStatus::
kAttestationsEnforcedMainHostUnenrolled &&
@@ -847,7 +873,7 @@ class SharedStoragePrefBrowserTest
#endif
}
void VerifyDebugErrorMessage(const std::string& error_message) {
virtual void VerifyDebugErrorMessage(const std::string& error_message) {
ASSERT_FALSE(SuccessExpected());
size_t found_pos = error_message.find("Debug");
if (!EnableDebugMessages()) {
@@ -4645,6 +4671,310 @@ IN_PROC_BROWSER_TEST_P(SharedStoragePrivateAggregationChromeBrowserTest,
histogram_tester_.ExpectUniqueSample(kWorkletNumPerPageHistogram, 1, 1);
}
class SharedStorageLocalUnpartitionedDataAccessBrowserTest
: public SharedStoragePrefBrowserTest {
public:
SharedStorageLocalUnpartitionedDataAccessBrowserTest() = default;
~SharedStorageLocalUnpartitionedDataAccessBrowserTest() override = default;
void SetUpOnMainThread() override {
// Fenced frame test helper should enable the feature
// "FencedFramesLocalUnpartitionedDataAccess" in its constructor, which is
// required for the tests.
ASSERT_TRUE(base::FeatureList::IsEnabled(
blink::features::kFencedFramesLocalUnpartitionedDataAccess));
SharedStoragePrefBrowserTest::SetUpOnMainThread();
}
// This always enrolls the host for Shared Storage, but only enrolls the host
// for fenced frame local unpartitioned data access exactly when enforcement
// and enrollment status is `kAttestationsEnforcedMainHostEnrolled`.
void MaybeEnrollMainHost(const GURL& main_url) override {
auto attestations_set =
privacy_sandbox::PrivacySandboxAttestationsGatedAPISet(
{privacy_sandbox::PrivacySandboxAttestationsGatedAPI::
kSharedStorage});
if (GetEnforcementAndEnrollmentStatus() ==
EnforcementAndEnrollmentStatus::kAttestationsEnforcedMainHostEnrolled) {
attestations_set.Put(privacy_sandbox::PrivacySandboxAttestationsGatedAPI::
kLocalUnpartitionedDataAccess);
}
privacy_sandbox::PrivacySandboxAttestationsMap attestations_map{
{net::SchemefulSite(main_url), attestations_set}};
SetAttestationsMap(attestations_map);
}
void VerifyDebugErrorMessage(const std::string& error_message) override {
ASSERT_FALSE(SuccessExpected());
size_t found_pos = error_message.find("Debug");
if (!EnableDebugMessages()) {
EXPECT_EQ(found_pos, std::string::npos);
return;
}
EXPECT_NE(found_pos, std::string::npos);
// The accessing site is always enrolled for Shared Storage. So the status
// only depends on Privacy Sandbox status.
int status = EnablePrivacySandbox() ? 4 : 1;
if (status == 4) {
ASSERT_FALSE(AllowThirdPartyCookies());
}
found_pos = error_message.find("status " + base::NumberToString(status));
EXPECT_NE(found_pos, std::string::npos);
}
content::RenderFrameHost*
CreateFencedFrameAndSet3rdPartyCookieAndFencedFrameHostAttestationSettings() {
EXPECT_TRUE(
NavigateToURL(GetActiveWebContents(),
https_server()->GetURL(kMainHost, kSimplePagePath)));
fenced_frame_url_ = https_server()->GetURL("a.test", kFencedFramePagePath);
content::RenderFrameHost* fenced_frame_rfh = content::CreateFencedFrame(
GetActiveWebContents()->GetPrimaryMainFrame(), fenced_frame_url_);
SetThirdPartyCookieSetting(fenced_frame_url_);
MaybeEnrollMainHost(fenced_frame_url_);
return fenced_frame_rfh;
}
bool SharedStorageSuccessExpected() const {
// This test suite always has the fenced frame URL enrolled for Shared
// Storage.
return EnablePrivacySandbox() && AllowThirdPartyCookies();
}
bool
SuccessExpectedForFFLocalUnpartitionedDataAccessWhenUntrustedNetworkAccessRevoked()
const {
return SuccessExpected();
}
GURL fenced_frame_url() const { return fenced_frame_url_; }
private:
// Enables the required features for fenced frame.
content::test::FencedFrameTestHelper fenced_frame_test_helper_;
GURL fenced_frame_url_;
};
IN_PROC_BROWSER_TEST_P(
SharedStorageLocalUnpartitionedDataAccessBrowserTest,
LocalUnpartitionedDataAccessAttestationWithoutUntrustedNetworkDisabled) {
// This always enrolls the fenced frame host for Shared Storage, but only
// enrolls the host for fenced frame local unpartitioned data access exactly
// when `ShouldEnrollMainHost()` is true.
content::RenderFrameHost* fenced_frame_rfh =
CreateFencedFrameAndSet3rdPartyCookieAndFencedFrameHostAttestationSettings();
content::EvalJsResult set_result = content::EvalJs(fenced_frame_rfh, R"(
sharedStorage.set('customKey', 'customValue');
)");
if (!AllowThirdPartyCookies()) {
// Enable block of all third party cookies in the tracking protection
// setting.
GetProfile()->GetPrefs()->SetBoolean(prefs::kBlockAll3pcToggleEnabled,
true);
}
if (SharedStorageSuccessExpected()) {
EXPECT_TRUE(set_result.error.empty());
WaitForHistograms({kTimingDocumentSetHistogram});
histogram_tester_.ExpectTotalCount(kTimingDocumentSetHistogram, 1);
} else {
// Shared Storage will be disabled.
EXPECT_TRUE(base::StartsWith(set_result.error,
GetSharedStorageDisabledErrorMessage()));
VerifyDebugErrorMessage(set_result.error);
}
// Set up console observer.
content::WebContentsConsoleObserver console_observer(GetActiveWebContents());
console_observer.SetFilter(MakeFilter(
{kFencedFrameLocalUnpartitionedDataAccessAttestationErrorPrefix,
kFencedFrameLocalUnpartitionedDataAccessDisabledBy3pcSettingError}));
// Attempt to access local unpartitioned data without revoking fenced frame
// untrusted network access.
content::EvalJsResult get_result = content::EvalJs(fenced_frame_rfh, R"(
sharedStorage.get('customKey');
)");
if (SuccessExpectedForFFLocalUnpartitionedDataAccessWhenUntrustedNetworkAccessRevoked()) {
// Fenced frame local unpartitioned data access is disabled when untrusted
// network access is not revoked.
ASSERT_FALSE(get_result.error.empty());
EXPECT_TRUE(base::StartsWith(
get_result.error,
GetFencedFrameLocalUnpartitionedDataAccessWithoutRevokeNetworkMessage()));
EXPECT_TRUE(console_observer.messages().empty());
} else if (!AllowThirdPartyCookies()) {
// Fenced frame local unpartitioned data access is disabled. A JavaScript
// error is shown.
EXPECT_TRUE(base::StartsWith(
get_result.error,
GetFencedFrameLocalUnpartitionedDataAccessDisabledMessage()));
// Fenced frame local unpartitioned data access is disabled when all third
// party cookies are blocked. Site cookie setting does not have effect.
ASSERT_TRUE(console_observer.Wait());
EXPECT_EQ(1u, console_observer.messages().size());
EXPECT_EQ(kFencedFrameLocalUnpartitionedDataAccessDisabledBy3pcSettingError,
base::UTF16ToUTF8(console_observer.messages()[0].message));
} else if (GetEnforcementAndEnrollmentStatus() ==
EnforcementAndEnrollmentStatus::
kAttestationsEnforcedMainHostUnenrolled) {
// Fenced frame local unpartitioned data access is disabled. A JavaScript
// error is shown.
EXPECT_TRUE(base::StartsWith(
get_result.error,
GetFencedFrameLocalUnpartitionedDataAccessDisabledMessage()));
// Fenced frame local unpartitioned data access is disabled when the
// accessing site is not enrolled. A console message is shown.
ASSERT_TRUE(console_observer.Wait());
EXPECT_EQ(1u, console_observer.messages().size());
EXPECT_EQ(
base::StrCat(
{kFencedFrameLocalUnpartitionedDataAccessAttestationErrorPrefix,
" ", url::Origin::Create(fenced_frame_url()).Serialize(),
" failed."}),
base::UTF16ToUTF8(console_observer.messages()[0].message));
} else {
// Shared storage is disabled. A JavaScript error is shown.
// Fenced frame local unpartitioned data access is disabled. A JavaScript
// error is shown.
ASSERT_FALSE(EnablePrivacySandbox());
EXPECT_TRUE(base::StartsWith(
get_result.error,
GetFencedFrameLocalUnpartitionedDataAccessDisabledMessage()));
}
}
IN_PROC_BROWSER_TEST_P(
SharedStorageLocalUnpartitionedDataAccessBrowserTest,
LocalUnpartitionedDataAccessAttestationWithUntrustedNetworkDisabled) {
// This always enrolls the fenced frame host for Shared Storage, but only
// enrolls the host for fenced frame local unpartitioned data access exactly
// when `ShouldEnrollMainHost()` is true.
content::RenderFrameHost* fenced_frame_rfh =
CreateFencedFrameAndSet3rdPartyCookieAndFencedFrameHostAttestationSettings();
content::EvalJsResult set_result = content::EvalJs(fenced_frame_rfh, R"(
sharedStorage.set('customKey', 'customValue');
)");
if (!AllowThirdPartyCookies()) {
// Enable block of all third party cookies in the tracking protection
// setting.
GetProfile()->GetPrefs()->SetBoolean(prefs::kBlockAll3pcToggleEnabled,
true);
}
if (SharedStorageSuccessExpected()) {
EXPECT_TRUE(set_result.error.empty());
WaitForHistograms({kTimingDocumentSetHistogram});
histogram_tester_.ExpectTotalCount(kTimingDocumentSetHistogram, 1);
} else {
// Shared Storage will be disabled.
EXPECT_TRUE(base::StartsWith(set_result.error,
GetSharedStorageDisabledErrorMessage()));
VerifyDebugErrorMessage(set_result.error);
}
// Set up console observer.
content::WebContentsConsoleObserver console_observer(GetActiveWebContents());
console_observer.SetFilter(MakeFilter(
{kFencedFrameLocalUnpartitionedDataAccessAttestationErrorPrefix,
kFencedFrameLocalUnpartitionedDataAccessDisabledBy3pcSettingError}));
// Disable untrusted network access.
EXPECT_TRUE(ExecJs(fenced_frame_rfh, R"(
window.fence.disableUntrustedNetwork();
)"));
// Access local unpartitioned data with fenced frame untrusted network access
// revoked.
content::EvalJsResult get_result = content::EvalJs(fenced_frame_rfh, R"(
sharedStorage.get('customKey');
)");
if (SuccessExpectedForFFLocalUnpartitionedDataAccessWhenUntrustedNetworkAccessRevoked()) {
// Fenced frame local unpartitioned data access is allowed when untrusted
// network access is revoked.
ASSERT_TRUE(get_result.error.empty());
EXPECT_EQ(get_result.ExtractString(), "customValue");
EXPECT_TRUE(console_observer.messages().empty());
WaitForHistograms({kTimingDocumentGetHistogram});
histogram_tester_.ExpectTotalCount(kTimingDocumentGetHistogram, 1);
} else if (!AllowThirdPartyCookies()) {
// Fenced frame local unpartitioned data access is disabled. A JavaScript
// error is shown.
EXPECT_TRUE(base::StartsWith(
get_result.error,
GetFencedFrameLocalUnpartitionedDataAccessDisabledMessage()));
// Fenced frame local unpartitioned data access is disabled when all third
// party cookies are blocked. Site cookie setting does not have effect.
ASSERT_TRUE(console_observer.Wait());
EXPECT_EQ(1u, console_observer.messages().size());
EXPECT_EQ(kFencedFrameLocalUnpartitionedDataAccessDisabledBy3pcSettingError,
base::UTF16ToUTF8(console_observer.messages()[0].message));
} else if (GetEnforcementAndEnrollmentStatus() ==
EnforcementAndEnrollmentStatus::
kAttestationsEnforcedMainHostUnenrolled) {
// Fenced frame local unpartitioned data access is disabled. A JavaScript
// error is shown.
EXPECT_TRUE(base::StartsWith(
get_result.error,
GetFencedFrameLocalUnpartitionedDataAccessDisabledMessage()));
// Fenced frame local unpartitioned data access is disabled when the
// accessing site is not enrolled. A console message is shown.
ASSERT_TRUE(console_observer.Wait());
EXPECT_EQ(1u, console_observer.messages().size());
EXPECT_EQ(
base::StrCat(
{kFencedFrameLocalUnpartitionedDataAccessAttestationErrorPrefix,
" ", url::Origin::Create(fenced_frame_url()).Serialize(),
" failed."}),
base::UTF16ToUTF8(console_observer.messages()[0].message));
} else {
// Shared storage is disabled. A JavaScript error is shown.
// Fenced frame local unpartitioned data access is disabled. A JavaScript
// error is shown.
ASSERT_FALSE(EnablePrivacySandbox());
EXPECT_TRUE(base::StartsWith(
get_result.error,
GetFencedFrameLocalUnpartitionedDataAccessDisabledMessage()));
}
}
INSTANTIATE_TEST_SUITE_P(
All,
SharedStorageLocalUnpartitionedDataAccessBrowserTest,
testing::Combine(
testing::Bool(),
testing::Bool(),
testing::Values(EnforcementAndEnrollmentStatus::kAttestationsUnenforced,
EnforcementAndEnrollmentStatus::
kAttestationsEnforcedMainHostUnenrolled,
#if BUILDFLAG(IS_ANDROID)
EnforcementAndEnrollmentStatus::
kAttestationsEnforcedMainHostEnrolled)),
#else
EnforcementAndEnrollmentStatus::
kAttestationsEnforcedMainHostEnrolled),
testing::Bool()),
#endif
DescribePrefBrowserTestParams);
class SharedStorageHeaderPrefBrowserTest : public SharedStoragePrefBrowserTest {
public:
SharedStorageHeaderPrefBrowserTest() {

@@ -157,6 +157,13 @@ class MockPrivateAggregationContentBrowserClientBase : public SuperClass {
std::string* out_debug_message,
bool* out_block_is_site_setting_specific),
(override));
MOCK_METHOD(bool,
IsFencedFramesLocalUnpartitionedDataAccessAllowed,
(content::BrowserContext * browser_context,
content::RenderFrameHost* rfh,
const url::Origin& top_frame_origin,
const url::Origin& accessing_origin),
(override));
MOCK_METHOD(bool,
IsPrivacySandboxReportingDestinationAttested,
(content::BrowserContext * browser_context,

@@ -7083,6 +7083,14 @@ class SharedStorageFencedFrameDocumentGetBrowserTest
blink::features::kFencedFramesLocalUnpartitionedDataAccess);
}
void SetUpOnMainThread() override {
SharedStorageFencedFrameInteractionBrowserTest::SetUpOnMainThread();
// Bypass local unpartitioned data access attestation check.
ON_CALL(browser_client(), IsFencedFramesLocalUnpartitionedDataAccessAllowed)
.WillByDefault(testing::Return(true));
}
private:
base::test::ScopedFeatureList fenced_frame_feature_;
};

@@ -61,6 +61,15 @@ using GetResult = storage::SharedStorageManager::GetResult;
} // namespace
const char kFencedFrameLocalUnpartitionedDataAccessDisabledMessage[] =
"Fenced frame local unpartitioned data access is disabled";
const char
kFencedFrameLocalUnpartitionedDataAccessWithoutRevokeNetworkMessage[] =
"sharedStorage.get() is not allowed in a fenced frame until network "
"access for it and all descendent frames has been revoked with "
"window.fence.disableUntrustedNetwork()";
const char kSharedStorageDisabledMessage[] = "sharedStorage is disabled";
const char kSharedStorageSelectURLDisabledMessage[] =
@@ -212,12 +221,12 @@ void SharedStorageDocumentServiceImpl::SharedStorageGet(
return;
}
std::string debug_message;
if (!IsSharedStorageAllowed(&debug_message)) {
std::move(callback).Run(blink::mojom::SharedStorageGetStatus::kError,
if (!IsLocalUnpartitionedDataAccessAllowed(
/*accessing_origin=*/render_frame_host().GetLastCommittedOrigin())) {
std::move(callback).Run(
blink::mojom::SharedStorageGetStatus::kError,
/*error_message=*/
GetSharedStorageErrorMessage(
debug_message, kSharedStorageDisabledMessage),
kFencedFrameLocalUnpartitionedDataAccessDisabledMessage,
/*value=*/{});
return;
}
@@ -227,9 +236,7 @@ void SharedStorageDocumentServiceImpl::SharedStorageGet(
std::move(callback).Run(
blink::mojom::SharedStorageGetStatus::kError,
/*error_message=*/
"sharedStorage.get() is not allowed in a fenced frame until network "
"access for it and all descendent frames has been revoked with "
"window.fence.disableUntrustedNetwork()",
kFencedFrameLocalUnpartitionedDataAccessWithoutRevokeNetworkMessage,
/*value=*/{});
return;
}
@@ -524,6 +531,16 @@ bool SharedStorageDocumentServiceImpl::IsSharedStorageAllowedForOrigin(
out_block_is_site_setting_specific);
}
bool SharedStorageDocumentServiceImpl::IsLocalUnpartitionedDataAccessAllowed(
const url::Origin& accessing_origin) {
return GetContentClient()
->browser()
->IsFencedFramesLocalUnpartitionedDataAccessAllowed(
render_frame_host().GetBrowserContext(), &render_frame_host(),
/*top_frame_origin=*/main_frame_origin_,
/*accessing_origin=*/accessing_origin);
}
bool SharedStorageDocumentServiceImpl::IsSharedStorageAddModuleAllowedForOrigin(
const url::Origin& accessing_origin,
std::string* out_debug_message,

@@ -29,6 +29,10 @@ class RenderFrameHost;
class SharedStorageWorkletHost;
class SharedStorageWorkletHostManager;
extern CONTENT_EXPORT const char
kFencedFrameLocalUnpartitionedDataAccessDisabledMessage[];
extern CONTENT_EXPORT const char
kFencedFrameLocalUnpartitionedDataAccessWithoutRevokeNetworkMessage[];
extern CONTENT_EXPORT const char kSharedStorageDisabledMessage[];
extern CONTENT_EXPORT const char kSharedStorageSelectURLDisabledMessage[];
extern CONTENT_EXPORT const char kSharedStorageAddModuleDisabledMessage[];
@@ -108,6 +112,9 @@ class CONTENT_EXPORT SharedStorageDocumentServiceImpl final
std::string* out_debug_message,
bool* out_block_is_site_specific);
bool IsLocalUnpartitionedDataAccessAllowed(
const url::Origin& accessing_origin);
bool IsSharedStorageAddModuleAllowedForOrigin(
const url::Origin& accessing_origin,
std::string* out_debug_message,

@@ -623,6 +623,14 @@ bool ContentBrowserClient::IsSharedStorageSelectURLAllowed(
return false;
}
bool ContentBrowserClient::IsFencedFramesLocalUnpartitionedDataAccessAllowed(
content::BrowserContext* browser_context,
content::RenderFrameHost* rfh,
const url::Origin& top_frame_origin,
const url::Origin& accessing_origin) {
return false;
}
bool ContentBrowserClient::IsPrivateAggregationAllowed(
content::BrowserContext* browser_context,
const url::Origin& top_frame_origin,

@@ -1129,6 +1129,14 @@ class CONTENT_EXPORT ContentBrowserClient {
std::string* out_debug_message,
bool* out_block_is_site_setting_specific);
// Allows the embedder to control if fenced frame gated Shared Storage API
// operations can happen in a given context.
virtual bool IsFencedFramesLocalUnpartitionedDataAccessAllowed(
content::BrowserContext* browser_context,
content::RenderFrameHost* rfh,
const url::Origin& top_frame_origin,
const url::Origin& accessing_origin);
// Allows the embedder to control if Private Aggregation API operations can
// happen in a given context.
//

@@ -107,6 +107,15 @@ GetSharedStorageWorkletHostManagerForStoragePartition(
->GetSharedStorageWorkletHostManager();
}
std::string GetFencedFrameLocalUnpartitionedDataAccessDisabledMessage() {
return kFencedFrameLocalUnpartitionedDataAccessDisabledMessage;
}
std::string
GetFencedFrameLocalUnpartitionedDataAccessWithoutRevokeNetworkMessage() {
return kFencedFrameLocalUnpartitionedDataAccessWithoutRevokeNetworkMessage;
}
std::string GetSharedStorageDisabledMessage() {
return kSharedStorageDisabledMessage;
}

@@ -36,6 +36,11 @@ SharedStorageWorkletHostManager*
GetSharedStorageWorkletHostManagerForStoragePartition(
StoragePartition* storage_partition);
std::string GetFencedFrameLocalUnpartitionedDataAccessDisabledMessage();
std::string
GetFencedFrameLocalUnpartitionedDataAccessWithoutRevokeNetworkMessage();
std::string GetSharedStorageDisabledMessage();
std::string GetSharedStorageSelectURLDisabledMessage();

@@ -524,6 +524,15 @@ bool ShellContentBrowserClient::IsSharedStorageSelectURLAllowed(
return true;
}
bool ShellContentBrowserClient::
IsFencedFramesLocalUnpartitionedDataAccessAllowed(
content::BrowserContext* browser_context,
content::RenderFrameHost* rfh,
const url::Origin& top_frame_origin,
const url::Origin& accessing_origin) {
return true;
}
bool ShellContentBrowserClient::IsCookieDeprecationLabelAllowed(
content::BrowserContext* browser_context) {
return true;

@@ -82,6 +82,11 @@ class ShellContentBrowserClient : public ContentBrowserClient {
const url::Origin& accessing_origin,
std::string* out_debug_message,
bool* out_block_is_site_setting_specific) override;
bool IsFencedFramesLocalUnpartitionedDataAccessAllowed(
content::BrowserContext* browser_context,
content::RenderFrameHost* rfh,
const url::Origin& top_frame_origin,
const url::Origin& accessing_origin) override;
bool IsCookieDeprecationLabelAllowed(
content::BrowserContext* browser_context) override;
bool IsCookieDeprecationLabelAllowedForContext(

@@ -363,6 +363,15 @@ bool HeadlessContentBrowserClient::IsSharedStorageSelectURLAllowed(
return true;
}
bool HeadlessContentBrowserClient::
IsFencedFramesLocalUnpartitionedDataAccessAllowed(
content::BrowserContext* browser_context,
content::RenderFrameHost* rfh,
const url::Origin& top_frame_origin,
const url::Origin& accessing_origin) {
return true;
}
void HeadlessContentBrowserClient::ConfigureNetworkContextParams(
content::BrowserContext* context,
bool in_memory,

@@ -101,7 +101,11 @@ class HeadlessContentBrowserClient : public content::ContentBrowserClient {
const url::Origin& accessing_origin,
std::string* out_debug_message,
bool* out_block_is_site_setting_specific) override;
bool IsFencedFramesLocalUnpartitionedDataAccessAllowed(
content::BrowserContext* browser_context,
content::RenderFrameHost* rfh,
const url::Origin& top_frame_origin,
const url::Origin& accessing_origin) override;
void ConfigureNetworkContextParams(
content::BrowserContext* context,
bool in_memory,