0

[shared storage] Check IsInterestGroupAPIAllowed() for interestGroups()

What: Check privacy sandbox settings for interestGroups().

How:
1. Add `browser_context` to the `IsInterestGroupAPIAllowed()` parameters
   to get the `PrivacySandboxSettings` for general permission check.
   This is because `render_frame_host` can be null (e.g., due to the
   initiator frame being destroyed and the worklet is in keep-alive
   phase). In this case, certain operations like console error will
   be skipped, but the core permission check will still be
   performed.
2. Introduce and use a new InterestGroupApiOperation::kRead type.

Bug: 367992703
Change-Id: I9e1b44efc3f67a408433e6284be82197bb594a73
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5936920
Reviewed-by: Andrey Kosyakov <caseq@chromium.org>
Reviewed-by: Russ Hamilton <behamilton@google.com>
Reviewed-by: Fiona Macintosh <fmacintosh@google.com>
Reviewed-by: Ben Kelly <wanderview@chromium.org>
Reviewed-by: Avi Drissman <avi@chromium.org>
Commit-Queue: Yao Xiao <yaoxia@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1370140}
This commit is contained in:
Yao Xiao
2024-10-17 18:05:33 +00:00
committed by Chromium LUCI CQ
parent a962c1b1e7
commit 99e9d6690c
22 changed files with 61 additions and 16 deletions

@ -3421,12 +3421,12 @@ std::string ChromeContentBrowserClient::GetWebBluetoothBlocklist() {
}
bool ChromeContentBrowserClient::IsInterestGroupAPIAllowed(
content::BrowserContext* browser_context,
content::RenderFrameHost* render_frame_host,
InterestGroupApiOperation operation,
const url::Origin& top_frame_origin,
const url::Origin& api_origin) {
Profile* profile =
Profile::FromBrowserContext(render_frame_host->GetBrowserContext());
Profile* profile = Profile::FromBrowserContext(browser_context);
auto* privacy_sandbox_settings =
PrivacySandboxSettingsFactory::GetForProfile(profile);
DCHECK(privacy_sandbox_settings);

@ -343,7 +343,8 @@ class ChromeContentBrowserClient : public content::ContentBrowserClient {
const url::Origin& requesting_origin,
const url::Origin& embedding_origin) override;
std::string GetWebBluetoothBlocklist() override;
bool IsInterestGroupAPIAllowed(content::RenderFrameHost* render_frame_host,
bool IsInterestGroupAPIAllowed(content::BrowserContext* browser_context,
content::RenderFrameHost* render_frame_host,
InterestGroupApiOperation operation,
const url::Origin& top_frame_origin,
const url::Origin& api_origin) override;

@ -2289,7 +2289,8 @@ class InterestGroupContentBrowserClient : public ChromeContentBrowserClient {
// ChromeContentBrowserClient overrides:
// This is needed so that the interest group related APIs can run without
// failing with the result AuctionResult::kSellerRejected.
bool IsInterestGroupAPIAllowed(content::RenderFrameHost* render_frame_host,
bool IsInterestGroupAPIAllowed(content::BrowserContext* browser_context,
content::RenderFrameHost* render_frame_host,
content::InterestGroupApiOperation operation,
const url::Origin& top_frame_origin,
const url::Origin& api_origin) override {

@ -73,6 +73,8 @@ constexpr char kIsFledgeSellAllowedHistogram[] =
"PrivacySandbox.IsFledgeSellAllowed";
constexpr char kIsFledgeBuyAllowedHistogram[] =
"PrivacySandbox.IsFledgeBuyAllowed";
constexpr char kIsFledgeReadAllowedHistogram[] =
"PrivacySandbox.IsFledgeReadAllowed";
constexpr char kIsPrivacySandboxReportingDestinationAttestedHistogram[] =
"PrivacySandbox.IsPrivacySandboxReportingDestinationAttested";
constexpr char kIsSharedStorageAllowedHistogram[] =
@ -158,6 +160,9 @@ void PrivacySandboxSettingsImpl::JoinFledgeHistogram(
case content::InterestGroupApiOperation::kBuy:
JoinHistogram(kIsFledgeBuyAllowedHistogram, status);
break;
case content::InterestGroupApiOperation::kRead:
JoinHistogram(kIsFledgeReadAllowedHistogram, status);
break;
}
}

@ -2407,6 +2407,7 @@ class FledgeFencedFrameOriginContentBrowserClient
// This is needed so that the interest group related APIs can run without
// failing with the result AuctionResult::kSellerRejected.
bool IsInterestGroupAPIAllowed(
content::BrowserContext* browser_context,
content::RenderFrameHost* render_frame_host,
ContentBrowserClient::InterestGroupApiOperation operation,
const url::Origin& top_frame_origin,

@ -70,7 +70,7 @@ bool IsAdAuctionHeadersEligibleInternal(Page& page,
}
if (!GetContentClient()->browser()->IsInterestGroupAPIAllowed(
render_frame_host,
render_frame_host->GetBrowserContext(), render_frame_host,
ContentBrowserClient::InterestGroupApiOperation::kSell,
top_frame_origin, request_origin)) {
base::UmaHistogramEnumeration(

@ -48,7 +48,8 @@ std::string Base64UrlDecode(std::string_view input) {
class InterceptingContentBrowserClient : public ContentBrowserClient {
public:
bool IsInterestGroupAPIAllowed(RenderFrameHost* render_frame_host,
bool IsInterestGroupAPIAllowed(content::BrowserContext* browser_context,
RenderFrameHost* render_frame_host,
InterestGroupApiOperation operation,
const url::Origin& top_frame_origin,
const url::Origin& api_origin) override {

@ -873,8 +873,8 @@ bool AdAuctionServiceImpl::IsInterestGroupAPIAllowed(
interest_group_api_operation,
const url::Origin& origin) const {
return GetContentClient()->browser()->IsInterestGroupAPIAllowed(
&render_frame_host(), interest_group_api_operation, main_frame_origin_,
origin);
render_frame_host().GetBrowserContext(), &render_frame_host(),
interest_group_api_operation, main_frame_origin_, origin);
}
void AdAuctionServiceImpl::OnAuctionComplete(

@ -226,7 +226,8 @@ class AllowInterestGroupContentBrowserClient : public TestContentBrowserClient {
const AllowInterestGroupContentBrowserClient&) = delete;
// ContentBrowserClient overrides:
bool IsInterestGroupAPIAllowed(content::RenderFrameHost* render_frame_host,
bool IsInterestGroupAPIAllowed(content::BrowserContext* browser_context,
content::RenderFrameHost* render_frame_host,
InterestGroupApiOperation operation,
const url::Origin& top_frame_origin,
const url::Origin& api_origin) override {

@ -72,7 +72,8 @@ class AllowInterestGroupContentBrowserClient
const AllowInterestGroupContentBrowserClient&) = delete;
// ContentBrowserClient overrides:
bool IsInterestGroupAPIAllowed(content::RenderFrameHost* render_frame_host,
bool IsInterestGroupAPIAllowed(content::BrowserContext* browser_context,
content::RenderFrameHost* render_frame_host,
InterestGroupApiOperation operation,
const url::Origin& top_frame_origin,
const url::Origin& api_origin) override {

@ -52,7 +52,8 @@ std::string base64Decode(std::string_view input) {
class InterceptingContentBrowserClient : public ContentBrowserClient {
public:
bool IsInterestGroupAPIAllowed(content::RenderFrameHost* render_frame_host,
bool IsInterestGroupAPIAllowed(content::BrowserContext* browser_context,
content::RenderFrameHost* render_frame_host,
InterestGroupApiOperation operation,
const url::Origin& top_frame_origin,
const url::Origin& api_origin) override {

@ -388,6 +388,7 @@ class AllowlistedOriginContentBrowserClient
// ContentBrowserClient overrides:
bool IsInterestGroupAPIAllowed(
content::BrowserContext* browser_context,
content::RenderFrameHost* render_frame_host,
ContentBrowserClient::InterestGroupApiOperation operation,
const url::Origin& top_frame_origin,

@ -82,6 +82,7 @@ class AllowAllContentBrowserClient
// ContentBrowserClient overrides:
bool IsInterestGroupAPIAllowed(
content::BrowserContext* browser_context,
content::RenderFrameHost* render_frame_host,
ContentBrowserClient::InterestGroupApiOperation operation,
const url::Origin& top_frame_origin,

@ -1137,6 +1137,18 @@ void SharedStorageWorkletHost::GetInterestGroups(
return;
}
RenderFrameHost* rfh =
document_service_ ? &document_service_->render_frame_host() : nullptr;
if (!GetContentClient()->browser()->IsInterestGroupAPIAllowed(
browser_context_, rfh, InterestGroupApiOperation::kRead,
main_frame_origin_, shared_storage_origin_)) {
std::move(callback).Run(
blink::mojom::GetInterestGroupsResult::NewErrorMessage(
"interestGroups() is not allowed."));
return;
}
interest_group_manager->GetInterestGroupsForOwner(
/*devtools_auction_id=*/{},
/*owner=*/shared_storage_origin_,

@ -544,6 +544,7 @@ std::string ContentBrowserClient::GetWebBluetoothBlocklist() {
}
bool ContentBrowserClient::IsInterestGroupAPIAllowed(
content::BrowserContext* browser_context,
content::RenderFrameHost* render_frame_host,
InterestGroupApiOperation operation,
const url::Origin& top_frame_origin,

@ -954,9 +954,15 @@ class CONTENT_EXPORT ContentBrowserClient {
using InterestGroupApiOperation = content::InterestGroupApiOperation;
// Returns whether |api_origin| on |top_frame_origin| can perform
// |operation| within the interest group API.
// Returns whether `api_origin` on `top_frame_origin` can perform `operation`
// within the interest group API.
//
// If `render_frame_host` is null (e.g., due to the initiator frame being
// destroyed for a keep-alive worklet), certain operations like console error
// will be skipped. However, the core permission check will still be
// performed.
virtual bool IsInterestGroupAPIAllowed(
content::BrowserContext* browser_context,
content::RenderFrameHost* render_frame_host,
InterestGroupApiOperation operation,
const url::Origin& top_frame_origin,

@ -9,7 +9,14 @@ namespace content {
// The possible operations performable by parties related to the Interest
// Group API.
enum class InterestGroupApiOperation { kJoin, kLeave, kUpdate, kSell, kBuy };
enum class InterestGroupApiOperation {
kJoin,
kLeave,
kUpdate,
kSell,
kBuy,
kRead
};
} // namespace content

@ -743,6 +743,7 @@ std::string WebTestContentBrowserClient::GetAcceptLangs(
}
bool WebTestContentBrowserClient::IsInterestGroupAPIAllowed(
content::BrowserContext* browser_context,
content::RenderFrameHost* render_frame_host,
InterestGroupApiOperation operation,
const url::Origin& top_frame_origin,

@ -118,7 +118,8 @@ class WebTestContentBrowserClient : public ShellContentBrowserClient {
ChildSpawnFlags flags) override;
#endif
std::string GetAcceptLangs(BrowserContext* context) override;
bool IsInterestGroupAPIAllowed(content::RenderFrameHost* render_frame_host,
bool IsInterestGroupAPIAllowed(content::BrowserContext* browser_context,
content::RenderFrameHost* render_frame_host,
InterestGroupApiOperation operation,
const url::Origin& top_frame_origin,
const url::Origin& api_origin) override;

@ -328,6 +328,7 @@ bool HeadlessContentBrowserClient::
}
bool HeadlessContentBrowserClient::IsInterestGroupAPIAllowed(
content::BrowserContext* browser_context,
content::RenderFrameHost* render_frame_host,
content::InterestGroupApiOperation operation,
const url::Origin& top_frame_origin,

@ -77,7 +77,8 @@ class HeadlessContentBrowserClient : public content::ContentBrowserClient {
// Returns whether |api_origin| on |top_frame_origin| can perform
// |operation| within the interest group API.
bool IsInterestGroupAPIAllowed(content::RenderFrameHost* render_frame_host,
bool IsInterestGroupAPIAllowed(content::BrowserContext* browser_context,
content::RenderFrameHost* render_frame_host,
content::InterestGroupApiOperation operation,
const url::Origin& top_frame_origin,
const url::Origin& api_origin) override;

@ -1739,6 +1739,7 @@ reviewer.
<variant name="IsFledgeBuyAllowed" summary="IsFledgeBuyAllowed"/>
<variant name="IsFledgeJoinAllowed" summary="IsFledgeJoinAllowed"/>
<variant name="IsFledgeLeaveAllowed" summary="IsFledgeLeaveAllowed"/>
<variant name="IsFledgeReadAllowed" summary="IsFledgeReadAllowed"/>
<variant name="IsFledgeSellAllowed" summary="IsFledgeSellAllowed"/>
<variant name="IsFledgeUpdateAllowed" summary="IsFledgeUpdateAllowed"/>
<variant name="IsLocalUnpartitionedDataAccessAllowed"