Skip to content

Commit

Permalink
[Credentialless]: Integrate with workers.
Browse files Browse the repository at this point in the history
Add cors-or-credentialless support to dedicated worker, service worker,
fetch resource loader and fetch resource response.

Fixed: 1199754
Bug: 199282,1199754
Change-Id: Icab249e8836164f2067701eea2e6dd588d12476f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2859448
Reviewed-by: Yifan Luo <lyf@chromium.org>
Reviewed-by: Kinuko Yasuda <kinuko@chromium.org>
Reviewed-by: Arthur Sonzogni <arthursonzogni@chromium.org>
Commit-Queue: Yifan Luo <lyf@chromium.org>
Cr-Commit-Position: refs/heads/master@{#880702}
  • Loading branch information
iVanlIsh authored and Chromium LUCI CQ committed May 8, 2021
1 parent 73bab81 commit a575de9
Show file tree
Hide file tree
Showing 11 changed files with 88 additions and 48 deletions.
Expand Up @@ -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()) {
Expand All @@ -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()) {
Expand Down Expand Up @@ -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(
Expand Down
Expand Up @@ -35,6 +35,7 @@ message ServiceWorkerRegistrationData {
enum CrossOriginEmbedderPolicyValue {
NONE_OR_NOT_EXIST = 0;
REQUIRE_CORP = 1;
CREDENTIALLESS = 2;
}

required int64 registration_id = 1;
Expand Down
Expand Up @@ -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<mojom::ServiceWorkerUserDataPtr> CreateUserData(
int64_t registration_id,
const std::vector<std::pair<std::string, std::string>>& key_value_pairs) {
Expand Down Expand Up @@ -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<ResourceRecordPtr> resources4;
resources4.push_back(CreateResource(4, data4.script, 400));
ASSERT_EQ(ServiceWorkerDatabase::Status::kOk,
Expand Down Expand Up @@ -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<ResourceRecordPtr> resources3;
resources3.push_back(CreateResource(3, data3.script, 300));
ASSERT_EQ(ServiceWorkerDatabase::Status::kOk,
Expand Down Expand Up @@ -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);
}

{
Expand All @@ -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);
}

{
Expand Down
Expand Up @@ -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 {
Expand Down Expand Up @@ -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<SiteInstanceImpl> site_instance =
SiteInstanceImpl::CreateForServiceWorker(
browser_context_, service_worker_url,
Expand Down
1 change: 1 addition & 0 deletions third_party/blink/renderer/core/DEPS
Expand Up @@ -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",
Expand Down
4 changes: 2 additions & 2 deletions third_party/blink/renderer/core/workers/dedicated_worker.cc
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand Down
Expand Up @@ -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"
Expand Down Expand Up @@ -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));
Expand Down
Expand Up @@ -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,
Expand Down
@@ -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.

This file was deleted.

This file was deleted.

0 comments on commit a575de9

Please sign in to comment.