Bug 228754 - Add initial support for Cross-Origin-Embedder-Policy (COEP)
Summary: Add initial support for Cross-Origin-Embedder-Policy (COEP)
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Page Loading (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Chris Dumez
URL: https://html.spec.whatwg.org/multipag...
Keywords: InRadar
Depends on: 228765
Blocks: 228755
  Show dependency treegraph
 
Reported: 2021-08-03 15:13 PDT by Chris Dumez
Modified: 2021-08-11 19:44 PDT (History)
15 users (show)

See Also:


Attachments
WIP patch (173.28 KB, patch)
2021-08-04 17:17 PDT, Chris Dumez
ews-feeder: commit-queue-
Details | Formatted Diff | Diff
WIP patch (174.76 KB, patch)
2021-08-05 08:38 PDT, Chris Dumez
no flags Details | Formatted Diff | Diff
WIP patch (177.05 KB, patch)
2021-08-05 09:08 PDT, Chris Dumez
no flags Details | Formatted Diff | Diff
WIP patch (179.43 KB, patch)
2021-08-05 11:34 PDT, Chris Dumez
no flags Details | Formatted Diff | Diff
WIP patch (178.11 KB, patch)
2021-08-05 12:22 PDT, Chris Dumez
no flags Details | Formatted Diff | Diff
Patch (204.44 KB, patch)
2021-08-05 15:51 PDT, Chris Dumez
no flags Details | Formatted Diff | Diff
Patch (207.85 KB, patch)
2021-08-05 19:41 PDT, Chris Dumez
no flags Details | Formatted Diff | Diff
Patch (211.47 KB, patch)
2021-08-05 21:35 PDT, Chris Dumez
no flags Details | Formatted Diff | Diff
Patch (211.58 KB, patch)
2021-08-09 18:56 PDT, Chris Dumez
no flags Details | Formatted Diff | Diff
Patch (212.32 KB, patch)
2021-08-11 15:38 PDT, Chris Dumez
no flags Details | Formatted Diff | Diff
Patch (211.97 KB, patch)
2021-08-11 16:17 PDT, Chris Dumez
no flags Details | Formatted Diff | Diff
Patch (212.12 KB, patch)
2021-08-11 18:46 PDT, Chris Dumez
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Chris Dumez 2021-08-03 15:13:50 PDT
Add initial support for Cross-Origin-Embedder-Policy (COEP):
- https://html.spec.whatwg.org/multipage/origin.html#coep
Comment 1 Chris Dumez 2021-08-04 17:17:12 PDT
Created attachment 434953 [details]
WIP patch
Comment 2 Chris Dumez 2021-08-05 08:38:33 PDT
Created attachment 434987 [details]
WIP patch
Comment 3 Chris Dumez 2021-08-05 09:08:45 PDT
Created attachment 434991 [details]
WIP patch
Comment 4 Chris Dumez 2021-08-05 11:34:41 PDT
Created attachment 435012 [details]
WIP patch
Comment 5 Chris Dumez 2021-08-05 12:22:50 PDT
Created attachment 435013 [details]
WIP patch
Comment 6 Chris Dumez 2021-08-05 15:51:27 PDT
Created attachment 435034 [details]
Patch
Comment 7 Chris Dumez 2021-08-05 19:41:08 PDT
Created attachment 435050 [details]
Patch
Comment 8 Chris Dumez 2021-08-05 21:35:07 PDT
Created attachment 435054 [details]
Patch
Comment 9 Radar WebKit Bug Importer 2021-08-09 15:11:58 PDT
<rdar://problem/81715011>
Comment 10 Darin Adler 2021-08-09 16:54:00 PDT
Comment on attachment 435054 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=435054&action=review

> Source/WebCore/loader/CrossOriginAccessControl.h:90
> +WEBCORE_EXPORT std::optional<ResourceError> validateCrossOriginResourcePolicy(const CrossOriginEmbedderPolicyValue&, const SecurityOrigin&, const URL&, const ResourceResponse&, ForNavigation);

A small scalar like CrossOriginEmbedderPolicyValue should just be passed by value; no reason to pass a const&.
Comment 11 Chris Dumez 2021-08-09 18:56:19 PDT
Created attachment 435232 [details]
Patch
Comment 12 Chris Dumez 2021-08-09 18:57:11 PDT
(In reply to Darin Adler from comment #10)
> Comment on attachment 435054 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=435054&action=review
> 
> > Source/WebCore/loader/CrossOriginAccessControl.h:90
> > +WEBCORE_EXPORT std::optional<ResourceError> validateCrossOriginResourcePolicy(const CrossOriginEmbedderPolicyValue&, const SecurityOrigin&, const URL&, const ResourceResponse&, ForNavigation);
> 
> A small scalar like CrossOriginEmbedderPolicyValue should just be passed by
> value; no reason to pass a const&.

Fixed, thanks. I was passing a CrossOriginEmbedderPolicy in an earlier iteration and failed to make this change when I started passing a CrossOriginEmbedderPolicyValue instead.
Comment 13 Alex Christensen 2021-08-11 15:05:45 PDT
Comment on attachment 435232 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=435232&action=review

> Source/WebCore/Modules/cache/DOMCacheEngine.h:51
> +    CORP

You may as well reduce the size of this enum class by adding : uint8_t.

> Source/WebCore/platform/network/HTTPParsers.h:64
>  enum class CrossOriginResourcePolicy {

ditto

> Source/WebCore/workers/service/server/RegistrationDatabase.cpp:53
> +static const uint64_t schemaVersion = 7;

Do we already have code that migrates old schemas or erases the old files?

> Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp:597
> +            String errorMessage = "Refused to display '" + response.url().stringCenterEllipsizedToLength() + "' in a frame because of Cross-Origin-Embedder-Policy.";

I feel like I've been told that makeString is more efficient than repeated operator+'s, but I'm not sure if that's still true.

> Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp:613
> +            String errorMessage = "Refused to load '" + response.url().stringCenterEllipsizedToLength() + "' worker because of Cross-Origin-Embedder-Policy.";

ditto.

> Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp:668
> +            if (protectedThis->m_networkLoad)

I don't understand what this check accomplishes.  I see it used before one other call site of didFailLoading but it doesn't seem necessary here.

> Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp:669
> +                protectedThis->didFailLoading(ResourceError { String { }, 0, url, "Worker load was blocked by Cross-Origin-Embedder-Policy"_s, ResourceError::Type::AccessControl });

Although there are a few other places that use the empty string as a domain, I think it would be nicer to use errorDomainWebKitInternal instead.

> Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp:883
> +        this->didFailLoading(ResourceError { String { }, 0, redirectRequest.url(), "Redirection was blocked by Cross-Origin-Embedder-Policy"_s, ResourceError::Type::AccessControl });

Ditto.   Error needs a real domain.

> Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp:150
> +            if (auto error = validateCrossOriginResourcePolicy(m_loader.parameters().parentCrossOriginEmbedderPolicy.value, *parentOrigin, m_currentRequest.url(), response, ForNavigation::Yes)) {

You have several added calls to validateCrossOriginResourcePolicy which seem like they could change behavior even if COEP is off.  Can they indeed cause errors that weren't there before?
Comment 14 Chris Dumez 2021-08-11 15:11:39 PDT
(In reply to Alex Christensen from comment #13)
> Comment on attachment 435232 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=435232&action=review
> 
> > Source/WebCore/Modules/cache/DOMCacheEngine.h:51
> > +    CORP
> 
> You may as well reduce the size of this enum class by adding : uint8_t.
> 
> > Source/WebCore/platform/network/HTTPParsers.h:64
> >  enum class CrossOriginResourcePolicy {
> 
> ditto
> 
> > Source/WebCore/workers/service/server/RegistrationDatabase.cpp:53
> > +static const uint64_t schemaVersion = 7;
> 
> Do we already have code that migrates old schemas or erases the old files?

There is already code that erases files for old schemas.

> 
> > Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp:597
> > +            String errorMessage = "Refused to display '" + response.url().stringCenterEllipsizedToLength() + "' in a frame because of Cross-Origin-Embedder-Policy.";
> 
> I feel like I've been told that makeString is more efficient than repeated
> operator+'s, but I'm not sure if that's still true.

Will switch.

> 
> > Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp:613
> > +            String errorMessage = "Refused to load '" + response.url().stringCenterEllipsizedToLength() + "' worker because of Cross-Origin-Embedder-Policy.";
> 
> ditto.

OK.

> 
> > Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp:668
> > +            if (protectedThis->m_networkLoad)
> 
> I don't understand what this check accomplishes.  I see it used before one
> other call site of didFailLoading but it doesn't seem necessary here.

I copied the logic from the other site. It is entirely possible this isn't necessary. I'll double check.

> 
> > Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp:669
> > +                protectedThis->didFailLoading(ResourceError { String { }, 0, url, "Worker load was blocked by Cross-Origin-Embedder-Policy"_s, ResourceError::Type::AccessControl });
> 
> Although there are a few other places that use the empty string as a domain,
> I think it would be nicer to use errorDomainWebKitInternal instead.
> 
> > Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp:883
> > +        this->didFailLoading(ResourceError { String { }, 0, redirectRequest.url(), "Redirection was blocked by Cross-Origin-Embedder-Policy"_s, ResourceError::Type::AccessControl });
> 
> Ditto.   Error needs a real domain.

Will Fix.

> 
> > Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp:150
> > +            if (auto error = validateCrossOriginResourcePolicy(m_loader.parameters().parentCrossOriginEmbedderPolicy.value, *parentOrigin, m_currentRequest.url(), response, ForNavigation::Yes)) {
> 
> You have several added calls to validateCrossOriginResourcePolicy which seem
> like they could change behavior even if COEP is off.  Can they indeed cause
> errors that weren't there before?

No, I do not think it is possible for COEP to cause errors in the network process when the feature flag is off in WebCore. All the checks in the network process rely on the COEP of the current document (or parent document), which are provided by WebCore. obtainCrossOriginEmbedderPolicy() in WebCore has an early return when the feature flag is disabled and so COEP for the current (or parent document) will always be the default (unsafe-none) when the feature flag is off.
Comment 15 Chris Dumez 2021-08-11 15:37:38 PDT
Comment on attachment 435232 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=435232&action=review

> Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp:594
> +    if (m_parameters.parentCrossOriginEmbedderPolicy.value != WebCore::CrossOriginEmbedderPolicyValue::UnsafeNone && m_parameters.sourceOrigin) {

Here m_parameters.parentCrossOriginEmbedderPolicy.value would be WebCore::CrossOriginEmbedderPolicyValue::UnsafeNone if the feature was disabled at runtime and therefore this function would be a no-op.

> Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp:610
> +    if (m_parameters.crossOriginEmbedderPolicy.value != WebCore::CrossOriginEmbedderPolicyValue::UnsafeNone && m_parameters.sourceOrigin) {

Here m_parameters.crossOriginEmbedderPolicy.value would be WebCore::CrossOriginEmbedderPolicyValue::UnsafeNone if the feature was disabled at runtime and therefore this function would be a no-op.
Comment 16 Chris Dumez 2021-08-11 15:38:30 PDT
Created attachment 435380 [details]
Patch
Comment 17 Alex Christensen 2021-08-11 16:13:40 PDT
Comment on attachment 435380 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=435380&action=review

> Source/WebCore/loader/CrossOriginEmbedderPolicy.h:99
> +template<> struct EnumTraits<WebCore::CrossOriginEmbedderPolicyValue> {

This is unnecessary because it uses bool as its storage, and the decoders already know that there are only 2 valid values
Comment 18 Chris Dumez 2021-08-11 16:15:47 PDT
(In reply to Alex Christensen from comment #17)
> Comment on attachment 435380 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=435380&action=review
> 
> > Source/WebCore/loader/CrossOriginEmbedderPolicy.h:99
> > +template<> struct EnumTraits<WebCore::CrossOriginEmbedderPolicyValue> {
> 
> This is unnecessary because it uses bool as its storage, and the decoders
> already know that there are only 2 valid values

Good to know, will fix. I had followed the pattern for COOP but COOP has more enum values.

Thanks for reviewing.
Comment 19 Chris Dumez 2021-08-11 16:17:04 PDT
Created attachment 435383 [details]
Patch
Comment 20 Darin Adler 2021-08-11 18:21:46 PDT
Comment on attachment 435232 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=435232&action=review

>>> Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp:597
>>> +            String errorMessage = "Refused to display '" + response.url().stringCenterEllipsizedToLength() + "' in a frame because of Cross-Origin-Embedder-Policy.";
>> 
>> I feel like I've been told that makeString is more efficient than repeated operator+'s, but I'm not sure if that's still true.
> 
> Will switch.

A call to makeString is more flexible than repeated operator+, since it can do things like format numbers without creating a temporary string, but for cases that both can handle, the efficiency should be exactly the same since operator+ does gather all the strings and then builds the result string only at the end.

Iā€™d like to eventually deprecate operator+, though.
Comment 21 Chris Dumez 2021-08-11 18:46:35 PDT
Created attachment 435390 [details]
Patch
Comment 22 EWS 2021-08-11 19:44:01 PDT
Committed r280953 (240459@main): <https://commits.webkit.org/240459@main>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 435390 [details].