diff --git a/components/services/storage/service_worker/service_worker_database.cc b/components/services/storage/service_worker/service_worker_database.cc index 5e118ebec0708..d108d6c2b22b6 100644 --- a/components/services/storage/service_worker/service_worker_database.cc +++ b/components/services/storage/service_worker/service_worker_database.cc @@ -1630,11 +1630,19 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::ParseRegistrationData( } if (data.has_cross_origin_embedder_policy_value()) { - (*out)->cross_origin_embedder_policy.value = - data.cross_origin_embedder_policy_value() == - ServiceWorkerRegistrationData::NONE_OR_NOT_EXIST - ? network::mojom::CrossOriginEmbedderPolicyValue::kNone - : network::mojom::CrossOriginEmbedderPolicyValue::kRequireCorp; + switch (data.cross_origin_embedder_policy_value()) { + case ServiceWorkerRegistrationData::REQUIRE_CORP: + (*out)->cross_origin_embedder_policy.value = + network::mojom::CrossOriginEmbedderPolicyValue::kRequireCorp; + break; + case ServiceWorkerRegistrationData::CREDENTIALLESS: + (*out)->cross_origin_embedder_policy.value = + network::mojom::CrossOriginEmbedderPolicyValue::kCredentialless; + break; + default: + (*out)->cross_origin_embedder_policy.value = + network::mojom::CrossOriginEmbedderPolicyValue::kNone; + } } if (data.has_cross_origin_embedder_policy_reporting_endpoint()) { @@ -1643,11 +1651,19 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::ParseRegistrationData( } if (data.has_cross_origin_embedder_policy_report_only_value()) { - (*out)->cross_origin_embedder_policy.report_only_value = - data.cross_origin_embedder_policy_report_only_value() == - ServiceWorkerRegistrationData::NONE_OR_NOT_EXIST - ? network::mojom::CrossOriginEmbedderPolicyValue::kNone - : network::mojom::CrossOriginEmbedderPolicyValue::kRequireCorp; + switch (data.cross_origin_embedder_policy_report_only_value()) { + case ServiceWorkerRegistrationData::REQUIRE_CORP: + (*out)->cross_origin_embedder_policy.report_only_value = + network::mojom::CrossOriginEmbedderPolicyValue::kRequireCorp; + break; + case ServiceWorkerRegistrationData::CREDENTIALLESS: + (*out)->cross_origin_embedder_policy.report_only_value = + network::mojom::CrossOriginEmbedderPolicyValue::kCredentialless; + break; + default: + (*out)->cross_origin_embedder_policy.report_only_value = + network::mojom::CrossOriginEmbedderPolicyValue::kNone; + } } if (data.has_cross_origin_embedder_policy_report_only_reporting_endpoint()) { @@ -1712,20 +1728,36 @@ void ServiceWorkerDatabase::WriteRegistrationDataInBatch( ServiceWorkerRegistrationData_ServiceWorkerUpdateViaCacheType>( registration.update_via_cache)); - data.set_cross_origin_embedder_policy_value( - registration.cross_origin_embedder_policy.value == - network::mojom::CrossOriginEmbedderPolicyValue::kRequireCorp - ? ServiceWorkerRegistrationData::REQUIRE_CORP - : ServiceWorkerRegistrationData::NONE_OR_NOT_EXIST); + switch (registration.cross_origin_embedder_policy.value) { + case network::mojom::CrossOriginEmbedderPolicyValue::kRequireCorp: + data.set_cross_origin_embedder_policy_value( + ServiceWorkerRegistrationData::REQUIRE_CORP); + break; + case network::mojom::CrossOriginEmbedderPolicyValue::kCredentialless: + data.set_cross_origin_embedder_policy_value( + ServiceWorkerRegistrationData::CREDENTIALLESS); + break; + default: + data.set_cross_origin_embedder_policy_value( + ServiceWorkerRegistrationData::NONE_OR_NOT_EXIST); + } if (registration.cross_origin_embedder_policy.reporting_endpoint) { data.set_cross_origin_embedder_policy_reporting_endpoint( registration.cross_origin_embedder_policy.reporting_endpoint.value()); } - data.set_cross_origin_embedder_policy_report_only_value( - registration.cross_origin_embedder_policy.report_only_value == - network::mojom::CrossOriginEmbedderPolicyValue::kRequireCorp - ? ServiceWorkerRegistrationData::REQUIRE_CORP - : ServiceWorkerRegistrationData::NONE_OR_NOT_EXIST); + switch (registration.cross_origin_embedder_policy.report_only_value) { + case network::mojom::CrossOriginEmbedderPolicyValue::kRequireCorp: + data.set_cross_origin_embedder_policy_report_only_value( + ServiceWorkerRegistrationData::REQUIRE_CORP); + break; + case network::mojom::CrossOriginEmbedderPolicyValue::kCredentialless: + data.set_cross_origin_embedder_policy_report_only_value( + ServiceWorkerRegistrationData::CREDENTIALLESS); + break; + default: + data.set_cross_origin_embedder_policy_report_only_value( + ServiceWorkerRegistrationData::NONE_OR_NOT_EXIST); + } if (registration.cross_origin_embedder_policy .report_only_reporting_endpoint) { data.set_cross_origin_embedder_policy_report_only_reporting_endpoint( diff --git a/components/services/storage/service_worker/service_worker_database.proto b/components/services/storage/service_worker/service_worker_database.proto index 550c4bf54ac7c..940b0efb60c7b 100644 --- a/components/services/storage/service_worker/service_worker_database.proto +++ b/components/services/storage/service_worker/service_worker_database.proto @@ -35,6 +35,7 @@ message ServiceWorkerRegistrationData { enum CrossOriginEmbedderPolicyValue { NONE_OR_NOT_EXIST = 0; REQUIRE_CORP = 1; + CREDENTIALLESS = 2; } required int64 registration_id = 1; diff --git a/components/services/storage/service_worker/service_worker_database_unittest.cc b/components/services/storage/service_worker/service_worker_database_unittest.cc index da1ecec5752bc..49d1c1a5355bb 100644 --- a/components/services/storage/service_worker/service_worker_database_unittest.cc +++ b/components/services/storage/service_worker/service_worker_database_unittest.cc @@ -105,6 +105,12 @@ network::CrossOriginEmbedderPolicy CrossOriginEmbedderPolicyRequireCorp() { return out; } +network::CrossOriginEmbedderPolicy CrossOriginEmbedderPolicyCredentialless() { + network::CrossOriginEmbedderPolicy out; + out.value = network::mojom::CrossOriginEmbedderPolicyValue::kCredentialless; + return out; +} + std::vector CreateUserData( int64_t registration_id, const std::vector>& key_value_pairs) { @@ -538,7 +544,8 @@ TEST(ServiceWorkerDatabaseTest, GetRegistrationsForStorageKey) { data4.version_id = 4000; data4.resources_total_size_bytes = 400; data4.script_response_time = base::Time::FromJsTime(4200); - data4.cross_origin_embedder_policy = CrossOriginEmbedderPolicyRequireCorp(); + data4.cross_origin_embedder_policy = + CrossOriginEmbedderPolicyCredentialless(); std::vector resources4; resources4.push_back(CreateResource(4, data4.script, 400)); ASSERT_EQ(ServiceWorkerDatabase::Status::kOk, @@ -610,6 +617,8 @@ TEST(ServiceWorkerDatabaseTest, GetAllRegistrations) { data3.script = URL(origin3, "/script3.js"); data3.version_id = 3000; data3.resources_total_size_bytes = 300; + data3.cross_origin_embedder_policy = + CrossOriginEmbedderPolicyCredentialless(); std::vector resources3; resources3.push_back(CreateResource(3, data3.script, 300)); ASSERT_EQ(ServiceWorkerDatabase::Status::kOk, @@ -2314,6 +2323,9 @@ TEST(ServiceWorkerDatabaseTest, CrossOriginEmbedderPolicyStoreRestore) { store_and_restore(policy); policy.value = network::mojom::CrossOriginEmbedderPolicyValue::kNone; store_and_restore(policy); + policy.value = + network::mojom::CrossOriginEmbedderPolicyValue::kCredentialless; + store_and_restore(policy); } { @@ -2330,6 +2342,9 @@ TEST(ServiceWorkerDatabaseTest, CrossOriginEmbedderPolicyStoreRestore) { policy.report_only_value = network::mojom::CrossOriginEmbedderPolicyValue::kNone; store_and_restore(policy); + policy.report_only_value = + network::mojom::CrossOriginEmbedderPolicyValue::kCredentialless; + store_and_restore(policy); } { diff --git a/content/browser/service_worker/service_worker_process_manager.cc b/content/browser/service_worker/service_worker_process_manager.cc index c8dc0d6a9ba94..26eb47a7777cf 100644 --- a/content/browser/service_worker/service_worker_process_manager.cc +++ b/content/browser/service_worker/service_worker_process_manager.cc @@ -17,6 +17,7 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/site_instance.h" #include "content/public/common/child_process_host.h" +#include "services/network/public/cpp/cross_origin_embedder_policy.h" #include "url/gurl.h" namespace content { @@ -125,8 +126,8 @@ ServiceWorkerProcessManager::AllocateWorkerProcess( : script_url; const bool is_coop_coep_cross_origin_isolated = !is_guest && cross_origin_embedder_policy.has_value() && - (cross_origin_embedder_policy->value == - network::mojom::CrossOriginEmbedderPolicyValue::kRequireCorp); + network::CompatibleWithCrossOriginIsolated( + cross_origin_embedder_policy->value); scoped_refptr site_instance = SiteInstanceImpl::CreateForServiceWorker( browser_context_, service_worker_url, diff --git a/third_party/blink/renderer/core/DEPS b/third_party/blink/renderer/core/DEPS index 97c5c7afe0389..2819ec2781e0b 100644 --- a/third_party/blink/renderer/core/DEPS +++ b/third_party/blink/renderer/core/DEPS @@ -75,6 +75,7 @@ include_rules = [ "+services/device/public/mojom/wake_lock.mojom-blink.h", "+services/metrics/public", "+services/network/public/cpp/cors/cors_error_status.h", + "+services/network/public/cpp/cross_origin_embedder_policy.h", "+services/network/public/cpp/features.h", "+services/network/public/cpp/ip_address_space_util.h", "+services/network/public/cpp/is_potentially_trustworthy.h", diff --git a/third_party/blink/renderer/core/workers/dedicated_worker.cc b/third_party/blink/renderer/core/workers/dedicated_worker.cc index e1d7e1515fa85..2b10c972ff529 100644 --- a/third_party/blink/renderer/core/workers/dedicated_worker.cc +++ b/third_party/blink/renderer/core/workers/dedicated_worker.cc @@ -10,6 +10,7 @@ #include "base/optional.h" #include "base/unguessable_token.h" #include "mojo/public/cpp/bindings/pending_remote.h" +#include "services/network/public/cpp/cross_origin_embedder_policy.h" #include "services/network/public/mojom/fetch_api.mojom-blink.h" #include "third_party/blink/public/common/blob/blob_utils.h" #include "third_party/blink/public/common/features.h" @@ -235,8 +236,7 @@ void DedicatedWorker::OnHostCreated( const network::CrossOriginEmbedderPolicy& parent_coep) { DCHECK(!base::FeatureList::IsEnabled(features::kPlzDedicatedWorker)); const RejectCoepUnsafeNone reject_coep_unsafe_none( - parent_coep.value == - network::mojom::CrossOriginEmbedderPolicyValue::kRequireCorp); + network::CompatibleWithCrossOriginIsolated(parent_coep)); if (options_->type() == "classic") { // Legacy code path (to be deprecated, see https://crbug.com/835717): // A worker thread will start after scripts are fetched on the current diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc index 0462554dc448c..f453effdd9a96 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc @@ -40,6 +40,7 @@ #include "mojo/public/cpp/bindings/pending_remote.h" #include "services/metrics/public/cpp/mojo_ukm_recorder.h" #include "services/metrics/public/cpp/ukm_builders.h" +#include "services/network/public/cpp/cross_origin_embedder_policy.h" #include "services/network/public/cpp/features.h" #include "services/network/public/mojom/blocked_by_response_reason.mojom-shared.h" #include "services/network/public/mojom/fetch_api.mojom-blink.h" @@ -982,8 +983,8 @@ void ResourceLoader::DidReceiveResponseInternal( // https://wicg.github.io/cross-origin-embedder-policy/#integration-html // TODO(crbug.com/1064920): Remove this once PlzDedicatedWorker ships. if (options.reject_coep_unsafe_none && - response.GetCrossOriginEmbedderPolicy() != - network::mojom::CrossOriginEmbedderPolicyValue::kRequireCorp && + !network::CompatibleWithCrossOriginIsolated( + response.GetCrossOriginEmbedderPolicy()) && !response.CurrentRequestUrl().ProtocolIsData() && !response.CurrentRequestUrl().ProtocolIs("blob")) { DCHECK(!base::FeatureList::IsEnabled(features::kPlzDedicatedWorker)); diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_response.cc b/third_party/blink/renderer/platform/loader/fetch/resource_response.cc index 76717a71a0eff..030702b5e2fb9 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_response.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_response.cc @@ -492,11 +492,16 @@ ResourceResponse::GetCrossOriginEmbedderPolicy() const { const std::string value = HttpHeaderField(kHeaderName).Utf8(); using Item = net::structured_headers::Item; const auto item = net::structured_headers::ParseItem(value); - if (!item || item->item.Type() != Item::kTokenType || - item->item.GetString() != "require-corp") { + if (!item || item->item.Type() != Item::kTokenType) { + return network::mojom::CrossOriginEmbedderPolicyValue::kNone; + } + if (item->item.GetString() == "require-corp") { + return network::mojom::CrossOriginEmbedderPolicyValue::kRequireCorp; + } else if (item->item.GetString() == "credentialless") { + return network::mojom::CrossOriginEmbedderPolicyValue::kCredentialless; + } else { return network::mojom::CrossOriginEmbedderPolicyValue::kNone; } - return network::mojom::CrossOriginEmbedderPolicyValue::kRequireCorp; } STATIC_ASSERT_ENUM(WebURLResponse::kHTTPVersionUnknown, diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/credentialless/dedicated-worker.tentative.https-expected.txt b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/credentialless/dedicated-worker.tentative.https-expected.txt index 6998fdca569db..7ecbf9ce7d5e1 100644 --- a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/credentialless/dedicated-worker.tentative.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/credentialless/dedicated-worker.tentative.https-expected.txt @@ -1,8 +1,8 @@ This is a testharness.js-based test. PASS dedicated-worker PASS fetch same-origin + credentialless worker -FAIL fetch same-origin assert_equals: coep:credentialless => expected "Worker blocked" but got "same_origin" -FAIL fetch cross-origin assert_equals: coep:credentialless => expected (string) "Worker blocked" but got (undefined) undefined +PASS fetch same-origin +PASS fetch cross-origin FAIL fetch cross-origin + credentialless worker assert_equals: coep:none => expected (undefined) undefined but got (string) "cross_origin" Harness: the test ran to completion. diff --git a/third_party/blink/web_tests/virtual/plz-dedicated-worker/external/wpt/html/cross-origin-embedder-policy/credentialless/dedicated-worker.tentative.https-expected.txt b/third_party/blink/web_tests/virtual/plz-dedicated-worker/external/wpt/html/cross-origin-embedder-policy/credentialless/dedicated-worker.tentative.https-expected.txt deleted file mode 100644 index 7ecbf9ce7d5e1..0000000000000 --- a/third_party/blink/web_tests/virtual/plz-dedicated-worker/external/wpt/html/cross-origin-embedder-policy/credentialless/dedicated-worker.tentative.https-expected.txt +++ /dev/null @@ -1,8 +0,0 @@ -This is a testharness.js-based test. -PASS dedicated-worker -PASS fetch same-origin + credentialless worker -PASS fetch same-origin -PASS fetch cross-origin -FAIL fetch cross-origin + credentialless worker assert_equals: coep:none => expected (undefined) undefined but got (string) "cross_origin" -Harness: the test ran to completion. - diff --git a/third_party/blink/web_tests/virtual/plz-service-worker/external/wpt/html/cross-origin-embedder-policy/credentialless/dedicated-worker.tentative.https-expected.txt b/third_party/blink/web_tests/virtual/plz-service-worker/external/wpt/html/cross-origin-embedder-policy/credentialless/dedicated-worker.tentative.https-expected.txt deleted file mode 100644 index 6998fdca569db..0000000000000 --- a/third_party/blink/web_tests/virtual/plz-service-worker/external/wpt/html/cross-origin-embedder-policy/credentialless/dedicated-worker.tentative.https-expected.txt +++ /dev/null @@ -1,8 +0,0 @@ -This is a testharness.js-based test. -PASS dedicated-worker -PASS fetch same-origin + credentialless worker -FAIL fetch same-origin assert_equals: coep:credentialless => expected "Worker blocked" but got "same_origin" -FAIL fetch cross-origin assert_equals: coep:credentialless => expected (string) "Worker blocked" but got (undefined) undefined -FAIL fetch cross-origin + credentialless worker assert_equals: coep:none => expected (undefined) undefined but got (string) "cross_origin" -Harness: the test ran to completion. -