Add efficient helpers in SchemefulSite for samesite origin comparisons
Adds SchemefulSite::IsSameSite methods which can compute the same site check efficiently (i.e. with fast early-return paths and no allocations). https://html.spec.whatwg.org/multipage/browsers.html#concept-site-same-site We also upgrade some callers. Bug: None Change-Id: Idd969769ff5e54500a25461c87ece193614eaa77 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6321328 Reviewed-by: Ari Chivukula <arichiv@chromium.org> Reviewed-by: Rakina Zata Amni <rakina@chromium.org> Reviewed-by: mmenke <mmenke@chromium.org> Reviewed-by: Christian Biesinger <cbiesinger@chromium.org> Commit-Queue: Charlie Harrison <csharrison@chromium.org> Reviewed-by: Chris Fredrickson <cfredric@chromium.org> Cr-Commit-Position: refs/heads/main@{#1429192}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
13a00fedfc
commit
e07e86eb2c
components/content_settings/core/common
content/browser
indexed_db
renderer_host
webid
net
third_party/blink/common/storage_key
url
@ -561,8 +561,7 @@ bool CookieSettingsBase::IsAllowedBySandboxValue(
|
|||||||
|
|
||||||
url::Origin origin = url::Origin::Create(url);
|
url::Origin origin = url::Origin::Create(url);
|
||||||
url::Origin first_party_origin = url::Origin::Create(first_party_url);
|
url::Origin first_party_origin = url::Origin::Create(first_party_url);
|
||||||
return origin.IsSameOriginWith(first_party_origin) ||
|
return net::SchemefulSite::IsSameSite(origin, first_party_origin);
|
||||||
net::SchemefulSite(origin) == net::SchemefulSite(first_party_origin);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
absl::variant<CookieSettingsBase::AllowAllCookies,
|
absl::variant<CookieSettingsBase::AllowAllCookies,
|
||||||
@ -834,12 +833,10 @@ bool CookieSettingsBase::IsAllowedByStorageAccessGrant(
|
|||||||
net::CookieSettingOverride::kStorageAccessGrantEligibleViaHeader)) {
|
net::CookieSettingOverride::kStorageAccessGrantEligibleViaHeader)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// The Storage Access API allows access in A(B(A)) case (or similar). Do the
|
// The Storage Access API allows access in A(B(A)) case (or similar).
|
||||||
// same-origin check first for performance reasons.
|
|
||||||
const url::Origin origin = url::Origin::Create(url);
|
const url::Origin origin = url::Origin::Create(url);
|
||||||
const url::Origin first_party_origin = url::Origin::Create(first_party_url);
|
const url::Origin first_party_origin = url::Origin::Create(first_party_url);
|
||||||
if (origin.IsSameOriginWith(first_party_origin) ||
|
if (net::SchemefulSite::IsSameSite(origin, first_party_origin)) {
|
||||||
net::SchemefulSite(origin) == net::SchemefulSite(first_party_origin)) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (GetContentSetting(url, first_party_url,
|
if (GetContentSetting(url, first_party_url,
|
||||||
|
@ -800,8 +800,8 @@ void IndexedDBContextImpl::ShutdownOnIDBSequence(base::TimeTicks start_time) {
|
|||||||
if (!delete_bucket && bucket_locator.storage_key.IsThirdPartyContext()) {
|
if (!delete_bucket && bucket_locator.storage_key.IsThirdPartyContext()) {
|
||||||
delete_bucket = std::ranges::any_of(
|
delete_bucket = std::ranges::any_of(
|
||||||
origins_to_purge_on_shutdown_, [&](const url::Origin& origin) {
|
origins_to_purge_on_shutdown_, [&](const url::Origin& origin) {
|
||||||
return net::SchemefulSite(origin) ==
|
return bucket_locator.storage_key.top_level_site().IsSameSiteWith(
|
||||||
bucket_locator.storage_key.top_level_site();
|
origin);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1626,8 +1626,8 @@ NavigationRequest::CreateForSynchronousRendererCommit(
|
|||||||
blink::mojom::AncestorChainBit ancestor_chain_bit =
|
blink::mojom::AncestorChainBit ancestor_chain_bit =
|
||||||
blink::mojom::AncestorChainBit::kSameSite;
|
blink::mojom::AncestorChainBit::kSameSite;
|
||||||
if (render_frame_host->ComputeSiteForCookies().IsNull() ||
|
if (render_frame_host->ComputeSiteForCookies().IsNull() ||
|
||||||
net::SchemefulSite(origin) != top_level_site ||
|
!top_level_site.IsSameSiteWith(origin) || !top_level_site.opaque() ||
|
||||||
!top_level_site.opaque() || origin.opaque()) {
|
origin.opaque()) {
|
||||||
ancestor_chain_bit = blink::mojom::AncestorChainBit::kCrossSite;
|
ancestor_chain_bit = blink::mojom::AncestorChainBit::kCrossSite;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6339,8 +6339,8 @@ void NavigationRequest::CommitNavigation() {
|
|||||||
commit_params_->should_have_sticky_user_activation =
|
commit_params_->should_have_sticky_user_activation =
|
||||||
!frame_tree_node_->IsMainFrame() &&
|
!frame_tree_node_->IsMainFrame() &&
|
||||||
old_frame_host->HasStickyUserActivation() &&
|
old_frame_host->HasStickyUserActivation() &&
|
||||||
net::SchemefulSite(old_frame_host->GetLastCommittedOrigin()) ==
|
net::SchemefulSite::IsSameSite(old_frame_host->GetLastCommittedOrigin(),
|
||||||
net::SchemefulSite(origin_to_commit);
|
origin_to_commit);
|
||||||
|
|
||||||
// Generate a UKM source and track it on NavigationRequest. This will be
|
// Generate a UKM source and track it on NavigationRequest. This will be
|
||||||
// passed down to the blink::Document to be created, if any, and used for UKM
|
// passed down to the blink::Document to be created, if any, and used for UKM
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "base/check.h"
|
#include "base/check.h"
|
||||||
#include "content/browser/webid/flags.h"
|
#include "content/browser/webid/flags.h"
|
||||||
#include "content/browser/webid/webid_utils.h"
|
#include "content/browser/webid/webid_utils.h"
|
||||||
|
#include "net/base/schemeful_site.h"
|
||||||
|
|
||||||
namespace content {
|
namespace content {
|
||||||
|
|
||||||
@ -359,7 +360,7 @@ bool FederatedProviderFetcher::ShouldSkipWellKnownEnforcementForIdp(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Skip if RP and IDP are same-site.
|
// Skip if RP and IDP are same-site.
|
||||||
return webid::IsSameSite(
|
return net::SchemefulSite::IsSameSite(
|
||||||
render_frame_host_->GetLastCommittedOrigin(),
|
render_frame_host_->GetLastCommittedOrigin(),
|
||||||
url::Origin::Create(fetch_result.identity_provider_config_url));
|
url::Origin::Create(fetch_result.identity_provider_config_url));
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "mojo/public/cpp/bindings/remote.h"
|
#include "mojo/public/cpp/bindings/remote.h"
|
||||||
#include "net/base/isolation_info.h"
|
#include "net/base/isolation_info.h"
|
||||||
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
|
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
|
||||||
|
#include "net/base/schemeful_site.h"
|
||||||
#include "net/base/url_util.h"
|
#include "net/base/url_util.h"
|
||||||
#include "net/cookies/site_for_cookies.h"
|
#include "net/cookies/site_for_cookies.h"
|
||||||
#include "net/http/http_request_headers.h"
|
#include "net/http/http_request_headers.h"
|
||||||
@ -738,7 +739,7 @@ std::pair<GURL, std::optional<ErrorUrlType>> GetErrorUrlAndType(
|
|||||||
return std::make_pair(error_url, ErrorUrlType::kSameOrigin);
|
return std::make_pair(error_url, ErrorUrlType::kSameOrigin);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!webid::IsSameSite(error_origin, idp_origin)) {
|
if (!net::SchemefulSite::IsSameSite(error_origin, idp_origin)) {
|
||||||
return std::make_pair(GURL(), ErrorUrlType::kCrossSite);
|
return std::make_pair(GURL(), ErrorUrlType::kCrossSite);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,10 +40,8 @@ constexpr net::registry_controlled_domains::PrivateRegistryFilter
|
|||||||
bool IsSameSiteWithAncestors(const url::Origin& origin,
|
bool IsSameSiteWithAncestors(const url::Origin& origin,
|
||||||
RenderFrameHost* render_frame_host) {
|
RenderFrameHost* render_frame_host) {
|
||||||
while (render_frame_host) {
|
while (render_frame_host) {
|
||||||
// Many cases are same-origin, so check that first to speed up the cases
|
if (!net::SchemefulSite::IsSameSite(
|
||||||
// where the check passes, as IsSameSite() is slower.
|
origin, render_frame_host->GetLastCommittedOrigin())) {
|
||||||
if (!origin.IsSameOriginWith(render_frame_host->GetLastCommittedOrigin()) &&
|
|
||||||
!IsSameSite(origin, render_frame_host->GetLastCommittedOrigin())) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
render_frame_host = render_frame_host->GetParent();
|
render_frame_host = render_frame_host->GetParent();
|
||||||
@ -119,10 +117,6 @@ bool IsEndpointSameOrigin(const GURL& identity_provider_config_url,
|
|||||||
.IsSameOriginWith(endpoint_url);
|
.IsSameOriginWith(endpoint_url);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsSameSite(const url::Origin& origin1, const url::Origin& origin2) {
|
|
||||||
return net::SchemefulSite(origin1) == net::SchemefulSite(origin2);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ShouldFailAccountsEndpointRequestBecauseNotSignedInWithIdp(
|
bool ShouldFailAccountsEndpointRequestBecauseNotSignedInWithIdp(
|
||||||
RenderFrameHost& host,
|
RenderFrameHost& host,
|
||||||
const GURL& identity_provider_config_url,
|
const GURL& identity_provider_config_url,
|
||||||
@ -464,7 +458,7 @@ FedCmRequesterFrameType ComputeRequesterFrameType(const RenderFrameHost& rfh,
|
|||||||
if (!rfh.GetParent()) {
|
if (!rfh.GetParent()) {
|
||||||
return FedCmRequesterFrameType::kMainFrame;
|
return FedCmRequesterFrameType::kMainFrame;
|
||||||
}
|
}
|
||||||
return IsSameSite(requester, embedder)
|
return net::SchemefulSite::IsSameSite(requester, embedder)
|
||||||
? FedCmRequesterFrameType::kSameSiteIframe
|
? FedCmRequesterFrameType::kSameSiteIframe
|
||||||
: FedCmRequesterFrameType::kCrossSiteIframe;
|
: FedCmRequesterFrameType::kCrossSiteIframe;
|
||||||
}
|
}
|
||||||
|
@ -53,10 +53,6 @@ std::optional<std::string> ComputeConsoleMessageForHttpResponseCode(
|
|||||||
bool IsEndpointSameOrigin(const GURL& identity_provider_config_url,
|
bool IsEndpointSameOrigin(const GURL& identity_provider_config_url,
|
||||||
const GURL& endpoint_url);
|
const GURL& endpoint_url);
|
||||||
|
|
||||||
// Returns whether the two origins are considered same-site (same eTLD+1). Also
|
|
||||||
// ensures that the scheme is the same.
|
|
||||||
bool IsSameSite(const url::Origin& origin1, const url::Origin& origin2);
|
|
||||||
|
|
||||||
// Returns whether FedCM should fail/skip the accounts endpoint request because
|
// Returns whether FedCM should fail/skip the accounts endpoint request because
|
||||||
// the user is not signed-in to the IdP.
|
// the user is not signed-in to the IdP.
|
||||||
bool ShouldFailAccountsEndpointRequestBecauseNotSignedInWithIdp(
|
bool ShouldFailAccountsEndpointRequestBecauseNotSignedInWithIdp(
|
||||||
|
@ -17,6 +17,54 @@
|
|||||||
|
|
||||||
namespace net {
|
namespace net {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// When `a_is_site` is true, `a` is actually a SchemefulSite internal
|
||||||
|
// `site_as_origin_`.
|
||||||
|
bool IsSameSiteInternal(const url::Origin& a,
|
||||||
|
const url::Origin& b,
|
||||||
|
bool a_is_site) {
|
||||||
|
if (a.opaque() || b.opaque()) {
|
||||||
|
return a == b;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a.scheme() != b.scheme()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The remaining code largely matches what `SameDomainOrHost()` would do, with
|
||||||
|
// one exception: we consider equal-but-empty hosts to be same-site.
|
||||||
|
|
||||||
|
// Host equality covers two cases:
|
||||||
|
// 1. Non-network schemes where origins are passed through unchanged.
|
||||||
|
// 2. Network schemes where equal hosts will have equal sites (and site
|
||||||
|
// computation is idempotent in cases where `a` is already a site).
|
||||||
|
if (a.host() == b.host()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string_view b_site = GetDomainAndRegistryAsStringPiece(
|
||||||
|
b, net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
|
||||||
|
|
||||||
|
// If either `a_site` or `b_site` is empty, their associated SchemefulSites
|
||||||
|
// will have origins passed through without modification, and the positive
|
||||||
|
// result would be covered in the host check above.
|
||||||
|
if (b_site.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Avoid re-calculating the site for `a` if it has already been done.
|
||||||
|
std::string_view a_site =
|
||||||
|
a_is_site
|
||||||
|
? a.host()
|
||||||
|
: GetDomainAndRegistryAsStringPiece(
|
||||||
|
a,
|
||||||
|
net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
|
||||||
|
return a_site == b_site;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
struct SchemefulSite::ObtainASiteResult {
|
struct SchemefulSite::ObtainASiteResult {
|
||||||
// This is only set if the supplied origin differs from calculated one.
|
// This is only set if the supplied origin differs from calculated one.
|
||||||
std::optional<url::Origin> origin;
|
std::optional<url::Origin> origin;
|
||||||
@ -101,6 +149,20 @@ SchemefulSite& SchemefulSite::operator=(const SchemefulSite& other) = default;
|
|||||||
SchemefulSite& SchemefulSite::operator=(SchemefulSite&& other) noexcept =
|
SchemefulSite& SchemefulSite::operator=(SchemefulSite&& other) noexcept =
|
||||||
default;
|
default;
|
||||||
|
|
||||||
|
// static
|
||||||
|
bool SchemefulSite::IsSameSite(const url::Origin& a, const url::Origin& b) {
|
||||||
|
bool same_site = IsSameSiteInternal(a, b, /*a_is_site=*/false);
|
||||||
|
DCHECK_EQ(same_site, SchemefulSite(a) == SchemefulSite(b));
|
||||||
|
return same_site;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SchemefulSite::IsSameSiteWith(const url::Origin& other) const {
|
||||||
|
bool same_site =
|
||||||
|
IsSameSiteInternal(internal_value(), other, /*a_is_site=*/true);
|
||||||
|
DCHECK_EQ(same_site, *this == SchemefulSite(other));
|
||||||
|
return same_site;
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
bool SchemefulSite::FromWire(const url::Origin& site_as_origin,
|
bool SchemefulSite::FromWire(const url::Origin& site_as_origin,
|
||||||
SchemefulSite* out) {
|
SchemefulSite* out) {
|
||||||
|
@ -77,6 +77,13 @@ class NET_EXPORT SchemefulSite {
|
|||||||
SchemefulSite& operator=(const SchemefulSite& other);
|
SchemefulSite& operator=(const SchemefulSite& other);
|
||||||
SchemefulSite& operator=(SchemefulSite&& other) noexcept;
|
SchemefulSite& operator=(SchemefulSite&& other) noexcept;
|
||||||
|
|
||||||
|
// These methods match the spec algorithm
|
||||||
|
// https://html.spec.whatwg.org/multipage/browsers.html#concept-site-same-site
|
||||||
|
// in an efficient way without allocating the SchemefulSite directly.
|
||||||
|
// They exactly match the semantics of SchemefulSite(a) == SchemefulSite(b).
|
||||||
|
static bool IsSameSite(const url::Origin& a, const url::Origin& b);
|
||||||
|
bool IsSameSiteWith(const url::Origin& other) const;
|
||||||
|
|
||||||
// Tries to construct an instance from a (potentially untrusted) value of the
|
// Tries to construct an instance from a (potentially untrusted) value of the
|
||||||
// internal `site_as_origin_` that got received over an RPC.
|
// internal `site_as_origin_` that got received over an RPC.
|
||||||
//
|
//
|
||||||
|
@ -31,11 +31,77 @@ TEST(SchemefulSiteTest, DifferentOriginSameRegisterableDomain) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(SchemefulSiteTest, IsSameSite) {
|
||||||
|
url::Origin opaque;
|
||||||
|
struct {
|
||||||
|
url::Origin a;
|
||||||
|
url::Origin b;
|
||||||
|
bool same_site;
|
||||||
|
} kTestCases[] = {
|
||||||
|
// Different scheme
|
||||||
|
{url::Origin::Create(GURL("http://foo.com/")),
|
||||||
|
url::Origin::Create(GURL("https://foo.com/")), false},
|
||||||
|
|
||||||
|
// Different eTLD+1
|
||||||
|
{url::Origin::Create(GURL("http://bar.com/")),
|
||||||
|
url::Origin::Create(GURL("http://foo.com/")), false},
|
||||||
|
|
||||||
|
// Different opaque
|
||||||
|
{url::Origin(), url::Origin(), false},
|
||||||
|
|
||||||
|
// Opaque / non-opaque
|
||||||
|
{url::Origin(), url::Origin::Create(GURL("http://foo.com/")), false},
|
||||||
|
|
||||||
|
// Different file origins
|
||||||
|
{url::Origin::Create(GURL("file://foo")),
|
||||||
|
url::Origin::Create(GURL("file://bar")), false},
|
||||||
|
|
||||||
|
// Different opaque, one derived from the other.
|
||||||
|
{opaque, opaque.DeriveNewOpaqueOrigin(), false},
|
||||||
|
|
||||||
|
// Same opaque
|
||||||
|
{opaque, opaque, true},
|
||||||
|
|
||||||
|
// Equal hosts
|
||||||
|
{url::Origin::Create(GURL("http://bar.foo.com/")),
|
||||||
|
url::Origin::Create(GURL("http://bar.foo.com/")), true},
|
||||||
|
|
||||||
|
// Equal and empty hosts
|
||||||
|
{url::Origin::Create(GURL("file://")),
|
||||||
|
url::Origin::Create(GURL("file://")), true},
|
||||||
|
|
||||||
|
// Equal file origins
|
||||||
|
{url::Origin::Create(GURL("file://foo")),
|
||||||
|
url::Origin::Create(GURL("file://foo")), true},
|
||||||
|
|
||||||
|
// Equal eTLD+1
|
||||||
|
{url::Origin::Create(GURL("http://bar.foo.com/")),
|
||||||
|
url::Origin::Create(GURL("http://baz.foo.com/")), true},
|
||||||
|
|
||||||
|
// Equal except port
|
||||||
|
{url::Origin::Create(GURL("http://bar.foo.com:80/")),
|
||||||
|
url::Origin::Create(GURL("http://baz.foo.com:81/")), true},
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const auto& test : kTestCases) {
|
||||||
|
SCOPED_TRACE(::testing::Message() << test.a << " " << test.b);
|
||||||
|
EXPECT_EQ(test.same_site, SchemefulSite::IsSameSite(test.a, test.b));
|
||||||
|
EXPECT_EQ(test.same_site, SchemefulSite::IsSameSite(test.b, test.a));
|
||||||
|
EXPECT_EQ(test.same_site, SchemefulSite(test.a).IsSameSiteWith(test.b));
|
||||||
|
EXPECT_EQ(test.same_site, SchemefulSite(test.b).IsSameSiteWith(test.a));
|
||||||
|
EXPECT_TRUE(SchemefulSite::IsSameSite(test.a, test.a));
|
||||||
|
EXPECT_TRUE(SchemefulSite::IsSameSite(test.b, test.b));
|
||||||
|
EXPECT_TRUE(SchemefulSite(test.a).IsSameSiteWith(test.a));
|
||||||
|
EXPECT_TRUE(SchemefulSite(test.b).IsSameSiteWith(test.b));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(SchemefulSiteTest, Operators) {
|
TEST(SchemefulSiteTest, Operators) {
|
||||||
// Create a list of origins that should all have different schemeful sites.
|
// Create a list of origins that should all have different schemeful sites.
|
||||||
// These are in ascending order.
|
// These are in ascending order.
|
||||||
auto kTestOrigins = std::to_array<url::Origin>({
|
auto kTestOrigins = std::to_array<url::Origin>({
|
||||||
url::Origin::Create(GURL("data:text/html,<body>Hello World</body>")),
|
url::Origin::Create(GURL("data:text/html,<body>Hello World</body>")),
|
||||||
|
url::Origin::Create(GURL("file://")),
|
||||||
url::Origin::Create(GURL("file://foo")),
|
url::Origin::Create(GURL("file://foo")),
|
||||||
url::Origin::Create(GURL("http://a.bar.test")),
|
url::Origin::Create(GURL("http://a.bar.test")),
|
||||||
url::Origin::Create(GURL("http://c.test")),
|
url::Origin::Create(GURL("http://c.test")),
|
||||||
@ -54,6 +120,9 @@ TEST(SchemefulSiteTest, Operators) {
|
|||||||
SCOPED_TRACE(site1.GetDebugString());
|
SCOPED_TRACE(site1.GetDebugString());
|
||||||
|
|
||||||
EXPECT_EQ(site1, site1);
|
EXPECT_EQ(site1, site1);
|
||||||
|
EXPECT_TRUE(
|
||||||
|
SchemefulSite::IsSameSite(kTestOrigins[first], kTestOrigins[first]));
|
||||||
|
EXPECT_TRUE(site1.IsSameSiteWith(kTestOrigins[first]));
|
||||||
EXPECT_FALSE(site1 < site1);
|
EXPECT_FALSE(site1 < site1);
|
||||||
|
|
||||||
// Check the operators work on copies.
|
// Check the operators work on copies.
|
||||||
@ -70,6 +139,9 @@ TEST(SchemefulSiteTest, Operators) {
|
|||||||
EXPECT_FALSE(site2 < site1);
|
EXPECT_FALSE(site2 < site1);
|
||||||
EXPECT_FALSE(site1 == site2);
|
EXPECT_FALSE(site1 == site2);
|
||||||
EXPECT_FALSE(site2 == site1);
|
EXPECT_FALSE(site2 == site1);
|
||||||
|
EXPECT_FALSE(
|
||||||
|
SchemefulSite::IsSameSite(kTestOrigins[first], kTestOrigins[second]));
|
||||||
|
EXPECT_FALSE(site1.IsSameSiteWith(kTestOrigins[second]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1151,8 +1151,7 @@ bool ShouldAddInitialStorageAccessApiOverride(
|
|||||||
StorageAccessNetRequestKind kind = kCrossSite;
|
StorageAccessNetRequestKind kind = kCrossSite;
|
||||||
if (request_initiator->IsSameOriginWith(origin)) {
|
if (request_initiator->IsSameOriginWith(origin)) {
|
||||||
kind = kSameOrigin;
|
kind = kSameOrigin;
|
||||||
} else if (SchemefulSite(request_initiator.value()) ==
|
} else if (SchemefulSite::IsSameSite(request_initiator.value(), origin)) {
|
||||||
SchemefulSite(origin)) {
|
|
||||||
kind = kCrossOriginSameSite;
|
kind = kCrossOriginSameSite;
|
||||||
}
|
}
|
||||||
if (emit_metrics) {
|
if (emit_metrics) {
|
||||||
|
@ -196,7 +196,7 @@ std::optional<StorageKey> StorageKey::Deserialize(std::string_view in) {
|
|||||||
// Neither should be opaque and they cannot match as that would mean
|
// Neither should be opaque and they cannot match as that would mean
|
||||||
// we should have simply encoded the origin and the input is malformed.
|
// we should have simply encoded the origin and the input is malformed.
|
||||||
if (key_origin.opaque() || key_top_level_site.opaque() ||
|
if (key_origin.opaque() || key_top_level_site.opaque() ||
|
||||||
net::SchemefulSite(key_origin) == key_top_level_site) {
|
key_top_level_site.IsSameSiteWith(key_origin)) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -556,7 +556,7 @@ StorageKey StorageKey::CreateFromOriginAndIsolationInfo(
|
|||||||
// CrossSite. Otherwise if the top level site matches the new origin and the
|
// CrossSite. Otherwise if the top level site matches the new origin and the
|
||||||
// site for cookies isn't empty it must be SameSite.
|
// site for cookies isn't empty it must be SameSite.
|
||||||
if (!origin.opaque() && !top_level_site.opaque() &&
|
if (!origin.opaque() && !top_level_site.opaque() &&
|
||||||
net::SchemefulSite(origin) == top_level_site &&
|
top_level_site.IsSameSiteWith(origin) &&
|
||||||
!isolation_info.site_for_cookies().IsNull()) {
|
!isolation_info.site_for_cookies().IsNull()) {
|
||||||
ancestor_chain_bit = blink::mojom::AncestorChainBit::kSameSite;
|
ancestor_chain_bit = blink::mojom::AncestorChainBit::kSameSite;
|
||||||
}
|
}
|
||||||
@ -588,13 +588,13 @@ StorageKey StorageKey::WithOrigin(const url::Origin& origin) const {
|
|||||||
// necessarily be kSameSite if the TLS and origin do match, so we won't
|
// necessarily be kSameSite if the TLS and origin do match, so we won't
|
||||||
// adjust the other way.
|
// adjust the other way.
|
||||||
if (ancestor_chain_bit == blink::mojom::AncestorChainBit::kSameSite &&
|
if (ancestor_chain_bit == blink::mojom::AncestorChainBit::kSameSite &&
|
||||||
net::SchemefulSite(origin) != top_level_site_) {
|
!top_level_site_.IsSameSiteWith(origin)) {
|
||||||
ancestor_chain_bit = blink::mojom::AncestorChainBit::kCrossSite;
|
ancestor_chain_bit = blink::mojom::AncestorChainBit::kCrossSite;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ancestor_chain_bit_if_third_party_enabled ==
|
if (ancestor_chain_bit_if_third_party_enabled ==
|
||||||
blink::mojom::AncestorChainBit::kSameSite &&
|
blink::mojom::AncestorChainBit::kSameSite &&
|
||||||
net::SchemefulSite(origin) != top_level_site_if_third_party_enabled) {
|
!top_level_site_if_third_party_enabled.IsSameSiteWith(origin)) {
|
||||||
ancestor_chain_bit_if_third_party_enabled =
|
ancestor_chain_bit_if_third_party_enabled =
|
||||||
blink::mojom::AncestorChainBit::kCrossSite;
|
blink::mojom::AncestorChainBit::kCrossSite;
|
||||||
}
|
}
|
||||||
@ -699,7 +699,7 @@ std::string StorageKey::Serialize() const {
|
|||||||
.GetTupleOrPrecursorTupleIfOpaque()
|
.GetTupleOrPrecursorTupleIfOpaque()
|
||||||
.Serialize(),
|
.Serialize(),
|
||||||
});
|
});
|
||||||
} else if (top_level_site_ == net::SchemefulSite(origin_)) {
|
} else if (top_level_site_.IsSameSiteWith(origin_)) {
|
||||||
// Case 2.
|
// Case 2.
|
||||||
return base::StrCat({
|
return base::StrCat({
|
||||||
origin_.GetURL().spec(),
|
origin_.GetURL().spec(),
|
||||||
@ -837,9 +837,8 @@ bool StorageKey::MatchesOriginForTrustedStorageDeletion(
|
|||||||
// SchemefulSites.
|
// SchemefulSites.
|
||||||
// TODO(crbug.com/1410196): Test that StorageKeys corresponding to anonymous
|
// TODO(crbug.com/1410196): Test that StorageKeys corresponding to anonymous
|
||||||
// iframes are handled appropriately here.
|
// iframes are handled appropriately here.
|
||||||
return IsFirstPartyContext()
|
return IsFirstPartyContext() ? (origin_ == origin)
|
||||||
? (origin_ == origin)
|
: (top_level_site_.IsSameSiteWith(origin));
|
||||||
: (top_level_site_ == net::SchemefulSite(origin));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StorageKey::MatchesRegistrableDomainForTrustedStorageDeletion(
|
bool StorageKey::MatchesRegistrableDomainForTrustedStorageDeletion(
|
||||||
@ -877,7 +876,7 @@ bool StorageKey::IsValid() const {
|
|||||||
// If this key's "normal" members indicate a 3p key, then the
|
// If this key's "normal" members indicate a 3p key, then the
|
||||||
// *_if_third_party_enabled counterparts must match them.
|
// *_if_third_party_enabled counterparts must match them.
|
||||||
if (!origin_.opaque() &&
|
if (!origin_.opaque() &&
|
||||||
(top_level_site_ != net::SchemefulSite(origin_) ||
|
(!top_level_site_.IsSameSiteWith(origin_) ||
|
||||||
ancestor_chain_bit_ != blink::mojom::AncestorChainBit::kSameSite)) {
|
ancestor_chain_bit_ != blink::mojom::AncestorChainBit::kSameSite)) {
|
||||||
if (top_level_site_ != top_level_site_if_third_party_enabled_) {
|
if (top_level_site_ != top_level_site_if_third_party_enabled_) {
|
||||||
return false;
|
return false;
|
||||||
@ -890,13 +889,13 @@ bool StorageKey::IsValid() const {
|
|||||||
// If top_level_site* is cross-site to origin, then ancestor_chain_bit* must
|
// If top_level_site* is cross-site to origin, then ancestor_chain_bit* must
|
||||||
// indicate that. An opaque top_level_site* must have a cross-site
|
// indicate that. An opaque top_level_site* must have a cross-site
|
||||||
// ancestor_chain_bit*.
|
// ancestor_chain_bit*.
|
||||||
if (top_level_site_ != net::SchemefulSite(origin_)) {
|
if (!top_level_site_.IsSameSiteWith(origin_)) {
|
||||||
if (ancestor_chain_bit_ != blink::mojom::AncestorChainBit::kCrossSite) {
|
if (ancestor_chain_bit_ != blink::mojom::AncestorChainBit::kCrossSite) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (top_level_site_if_third_party_enabled_ != net::SchemefulSite(origin_)) {
|
if (!top_level_site_if_third_party_enabled_.IsSameSiteWith(origin_)) {
|
||||||
if (ancestor_chain_bit_if_third_party_enabled_ !=
|
if (ancestor_chain_bit_if_third_party_enabled_ !=
|
||||||
blink::mojom::AncestorChainBit::kCrossSite) {
|
blink::mojom::AncestorChainBit::kCrossSite) {
|
||||||
return false;
|
return false;
|
||||||
@ -908,11 +907,11 @@ bool StorageKey::IsValid() const {
|
|||||||
if (nonce_->is_empty()) {
|
if (nonce_->is_empty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (top_level_site_ != net::SchemefulSite(origin_)) {
|
if (!top_level_site_.IsSameSiteWith(origin_)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (top_level_site_if_third_party_enabled_ != net::SchemefulSite(origin_)) {
|
if (!top_level_site_if_third_party_enabled_.IsSameSiteWith(origin_)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,6 +229,9 @@ class COMPONENT_EXPORT(URL) Origin {
|
|||||||
// are exact matches. Two opaque origins are same-origin only if their
|
// are exact matches. Two opaque origins are same-origin only if their
|
||||||
// internal nonce values match. A non-opaque origin is never same-origin with
|
// internal nonce values match. A non-opaque origin is never same-origin with
|
||||||
// an opaque origin.
|
// an opaque origin.
|
||||||
|
//
|
||||||
|
// If you are looking for a same _site_ check between origins, see
|
||||||
|
// net::SchemefulSite::IsSameSite.
|
||||||
bool IsSameOriginWith(const Origin& other) const;
|
bool IsSameOriginWith(const Origin& other) const;
|
||||||
|
|
||||||
// Non-opaque origin is "same-origin" with `url` if their schemes, hosts, and
|
// Non-opaque origin is "same-origin" with `url` if their schemes, hosts, and
|
||||||
|
Reference in New Issue
Block a user