#742: COEP reflection

Visit on Github.

Opened May 31, 2022

Bonjour le TAG!

I'm requesting a Early design review of COEP reflection.

Description

Add the API:

self.crossOriginEmbedderPolicy;

It reflects the environment's cross-origin-embedder-policy's value.

The possibles values are: unsafe-none, credentialless, and require-corp.

Question for w3ctag

The initial design is to add the API as part of the global object, similarly to the pre-existing crossOriginIsolated:

window.crossOriginIsolated         [pre-existing]
window.crossOriginEmbedderPolicy   [new]

Should we continue adding API one by one here? @mikewest suggested this could potentially be nested behind a new window.policies since COEP is part of the policy container. It might also make sense. WDYT?

Links

Further details:

  • I have reviewed the TAG's Web Platform Design Principles
  • The group where the incubation/design work on this is being done (or is intended to be done in the future): This is a simple HTML PR. Should I move the explainer toward WICG?
  • The group where standardization of this work is intended to be done ("unknown" if not known): Unknown.
  • Existing major pieces of multi-stakeholder review or discussion of this design: This was initially discussed here: https://github.com/whatwg/html/issues/7912
  • Major unresolved issues with or opposition to this design: No opposition. However, an interrogation about where the API should be located.
  • This work is being funded by: Google

Discussions

Comment by @ArthurSonzogni Jun 20, 2022 (See Github)

Gentle ping ;-)

Both Webkit and Mozilla replied adding this API looks reasonable. They don't have a strong opinion about the API location. Would you have some opinion before I proceed with enabling this by default in Chrome?

Comment by @torgo Jun 22, 2022 (See Github)

Hi @ArthurSonzogni we're putting this on the agenda for next week so hope to be back to you by EOD Wednesday.

Discussed Jul 1, 2022 (See Github)

Peter: already a ?? cross origin embedder policy

Peter: maybe instead of ... put them all in the window object - makes sense to me.

... if they create a policy object would you expect to see all the other policies there?

Rossen: in their S&P... there is a costly and polyfillable thing and this is an API to let you do it

Dan: jumps right into talking about solution and assumes a whole ton of knowledge without bringing up to speed on the problem and the space.

Peter: There's a PR against the HTML spec... the motivation here is for ads... to know if they will be effected by this policy...

Hadley: this isn't even in WICG... Opening comment - "this is a simple PR" on HTML...

@ArthurSonzogni, 

We will be able to review this if you can provide [an explainer](https://github.com/w3ctag/tag.w3.org/blob/main/explainers/index.md) that puts this in a bit more context.  Please remember that although we are often reviewing security-related proposals, we do not share all the back story of this proposal and how it fits together with other technologies.  What is the user need that is being serviced here?  What kinds of threats does this protect the user from?  How can the developer employ this technique?  Etc... 

Lacking use cases we can follow and review, we encourage use of our explainer template in order to capture all the other important bits in a single place - other considerations, code examples, privacy, security and a11y considerations etc. Can you please write one?

Also: in your response to question 2 of the s&p questionnaire it's a little confusing: do you expose or do you not expose the info specified?

Rossen: leaves feedack

Discussed Jul 1, 2022 (See Github)

Dan: response from Mike West.

Peter: we're concerned about the primary use case. I can leave a comment.

Discussed Jul 1, 2022 (See Github)

peter leaving additional comment

Peter: ads to detect they are in a less restrictive env.

Tess: It's not much of a stretch - we know there are actors out there who will get away with whatever they can get away with.

Peter: making it easier to do the bad behaviour - is the jist.

Comment by @atanassov Jul 11, 2022 (See Github)

@ArthurSonzogni,

We will be able to review this if you can provide an explainer that puts this in a bit more context. Please remember that although we are often reviewing security-related proposals, we do not share all the back story of this proposal and how it fits together with other technologies. What is the user need that is being serviced here? What kinds of threats does this protect the user from? How can the developer employ this technique? Etc...

Lacking use cases we can follow and review, we encourage use of our explainer template in order to capture all the other important bits in a single place - other considerations, code examples, privacy, security and a11y considerations etc. Can you please write one?

Also: in your response to question 2 of the Security and Privacy questionnaire it's a little confusing: do you expose, or do you not expose the info specified?

Comment by @ArthurSonzogni Jul 13, 2022 (See Github)

Thanks @atanassov for your initial look! I updated the explainer to follow more closely the template. See diff.

Also: in your response to question 2 of the Security and Privacy questionnaire it's a little confusing: do you expose, or do you not expose the info specified?

We expose an information that was previously deductible via other means. It is polyfillable.

Comment by @hadleybeeman Jul 14, 2022 (See Github)

Hi @ArthurSonzogni, this is a good start. What's still missing is a discussion of the user need. For example: as a user, I need [] so that I can [], and then how this API accomplishes that.

As far as we can tell, this is telling the site when the security features are turned off. Can you help us to understand the user benefit? And who are the expected users of this feature?

Comment by @mikewest Jul 14, 2022 (See Github)

Hey @hadleybeeman and @atanassov!

This feature (like Window.isSecureContext, Window.crossOriginIsolated, and Document.permissionsPolicy, etc.) aims to provide a pages' author with information about the security properties a given page has opted-into. These properties govern certain subtle aspects of the page's behavior, and potentially impose requirements on resources the page attempts to embed. @ArthurSonzogni's explainer lays out a few of those potential decision points in the "Motivating Use Cases" section.

While I appreciate your laser-focus on the end user, this feature's impact on the users' experience is quite attenuated, as it aims to provide developers with information that helps them construct a page in a reasonable way by understanding the constraints within which they're working. This is particularly relevant for libraries, ads, widgets, etc. that need to function correctly in a wide range of environments, but it's certainly also useful for authors aiming to gradually migrate towards more secure setups, such that they might be responsible both for pages that assert a COEP, and pages that don't.

Does that help?

Comment by @plinss Jul 18, 2022 (See Github)

Our primary concern here is the way that this capability will ultimately be used. We're happy that there is all sorts of work going on to make web pages more secure and preserve more of the user's privacy. However, it seems like by allowing authors to detect when they're in a more locked-down environment, we're really giving them the ability to determine that they're in a more permissive environment and rather than assume less capability, opt-in to older behaviors that may be more abusive to the end user.

Is this really creating a better web or just allowing the "old way" to carry on longer?

Comment by @ArthurSonzogni Jul 24, 2022 (See Github)

Sorry for the delay, I was on vacation. Thanks @mikewest for your post, and @plinss for your reply! I wasn't expecting a push back on this feature. You provided nice question/arguments, let's see if I can provide the right ones in a reply:

opt-in to older behaviors that may be more abusive to the end user.

Could you please let me understand why you believe the default COEP value may be abusive to the end user? I don't believe it is. This is key to the whole question.

We created COEP:require-corp and COEP:credentialless, as dependencies to access more powerful features like SharedArrayBuffer or high resolution timers. The default COEP:unsafe-none is still used by 99.996% of top-level documents. I know 'unsafe' looks like a scary name. It was done purposefully as an incentive for developers to prefer the two other values, if they can. This would be 'unsafe' only in a context where access to SharedArrayBuffer or high resolution timer is granted, we don't do this. So that's fine unconditionally. If we did, the attacker could exploit the Spectre vulnerability with sufficient bandwidth and they might extract non public data without opt-in from weak cross-origin entities.

On the other side, COEP reflection is already polyfillable. If there was a reason not to expose this information, the battle would have been lost already. So not reflecting its own COEP state doesn't help anything.

You might now ask: Why a supported implementation is preferable to a ~polyfill? The polyfill requires sending some fetch() requests and observe the side effects of COEP:

  • Waiting for fetch() implies delays. This is important for some developers to avoid wasting time.
  • A fetch blocked by COEP issues a devtool console error message. Legitimate developers don't want the added noise.
  • A fetch blocked by COEP issues a report for those using COEP reporting. Legitimate developers don't want noises in their alerts.

So, at best this is just annoying for legitimate developers, without preventing sufficiently motivated ones from accessing the information.

COEP:reflection is a part of anonymous iframe whose goal is to allow more website to deploy COEP.

Is this somehow convincing?

Comment by @mikewest Jul 26, 2022 (See Github)

To pile on a bit:

However, it seems like by allowing authors to detect when they're in a more locked-down environment, we're really giving them the ability to determine that they're in a more permissive environment

I think this is a misunderstanding. Or, at least, it's not as clear cut as something like Secure Contexts, as COEP is a tradeoff.

COEP imposes a restriction on your ability to load resources. Rather than being able to load anything at all via no-cors requests (e.g. <img>/<script>), a COEP of require-corp ensures that you can only load resources that opt-into being loaded in your context. In one sense, then, COEP reduces your capability.

In another sense, though, COEP is part of a structure that we believe allows us to enable powerful primitives like Shared Array Buffers. which could potentially enable side-channel attacks. If you opt-into COEP and COOP, you get SABs on the one hand, memory profiling APIs on the other, and whatever else we come up with behind the [CrossOriginIsolated] IDL attribute.

If we've done our jobs, developers on both sides of the COEP opt-in are appropriately empowered. Without COEP: require-corp, sites can include resources through no-cors requests, but they can't attack those resources with high-powered primitives that enable Spectre. With COEP: require-corp, sites can use those powerful primitives, but can't attack unwary resources.

With that in mind, I'm a little confused about the scenarios that you're worried about. Can you help me understand what developers would do with explicit reflection of a page's COEP that would leave the web worse off than it was in the status quo?

Comment by @plinss Jul 26, 2022 (See Github)

We understand that this isn't making anything worse than the status quo, our concern is more about 'is this helping to preserve the status quo'?

To be more explicit, the primary stated use case seems to be for ads to choose their behavior. What would the different behavior be?

e.g. Without this feature, will ads be more likely to assume the COEP restrictions are in place and have a lighter touch (that is presumably better for the end user), where having this feature allows them to detect when they're in an unrestricted context and perpetuate exiting behavior (which may not be as desirable for the end user)?

Also, our concern here is a bit broader than COEP reflection, but also applies to other policies that may be exposed in the future.

Comment by @ArthurSonzogni Jul 27, 2022 (See Github)

For this use case in particular, I will ask them to reply directly here.

My recollection is that for publishers who want to continue monetizing their site and use SharedArrayBuffers, they have no choice other than registering to the reverse origin trial. It was meant to be temporary, we need to close it. If no solution is provided, they will be broken. We identified anonymous iframe as a solution.

For ads, knowing if COEP is enabled allows to know beforehand the <iframe> will be blocked by COEP, and use anonymous iframe as an alternative. If COEP reflection is canceled here, I see those alternatives:

  1. Use anonymous iframe unconditionally. This is almost similar to getting a stronger version of storage partitioning in advance + losing autofill + losing popups with opener. There might be also some performance cost due to additional partitioning. I am not sure they can afford it.
  2. Use the polyfill described above. Issues are delay and noises in devtools/reports.
  3. Using window.crossOriginIsolated as a proxy for window.crossOriginEmbedderPolicy. Publisher using COEP without COOP would be left without a solution.
  4. Ask individual publisher to expose their COEP state to the ads script.
Discussed Aug 1, 2022 (See Github)

Dan: Peter left a message.. can we close?

Peter: they haven't really responded, we got a reply from someone else. We pushed back saying doesn't this just help advertisers keep abusing users. They have not answered that.

Comment by @torgo Aug 15, 2022 (See Github)

Hi folks - just reviewing this today and it doesn't look like the core concern Peter raised has been addressed. Is there any further info you can provide on the use cases and user benefit?

Comment by @zhengweiwithoutthei Aug 17, 2022 (See Github)

Hi there, Zheng from Google Ad Manger.

We would like to support COEP enabled publisher to continue monetizing their sites where ads are currently broken (unless participated in the reverse OT). We want to be able to know if COEP is enabled and use anonymous iframe as an alternative. Currently there isn't a way to accurately identify COEP traffic. I can see the proposal discussed there to be very useful for this purpose.

Regarding those alternatives:

  1. Marking iframe as anonymous would result in the ad iframe have no access to existing cookies or shared storage. This will have a significant consequences in terms of ad performance. It is not something we want to do unconditionally.
  2. The polyfill will impose unnecessary latency and resource cost to the user.
  3. This is an acceptable alternative if the proposed reflection is rejected. The consequences is that ads on publisher sites that use COEP but COOP will be broken.
  4. In practice, we try not to make the publisher to retag or explicitly expose the config of their site to the ads script if not absolute necessary.
Discussed Nov 1, 2022 (See Github)

Dan: their response

Peter: response seems to support my point.. keep doing what they're doing with accses to extra cookies and data for as long as possible

Amy: they want to avoid anonymous iframe so they can keep doing bad 3p cookies stuff? we reviewed that positively. How does this relate to fenced frames

Peter: not sure difference between fenced frames and iframes. Their response says we don't want to switch to anonymous iframe as that will have consequences for our ad performance. But they need a different solution than just not doing the privacy-enhancing stuff.

Dan: Mike wrote a bunch of stuff and asked for clarification.. Peter wrote clarification and Mike didn't respond, someone else did. We need to signal to them we're not happy with this?

Peter: It looks like there are other uses related to sharedarraybuffers, maybe. Clearly the obvious use case is ads and they're making that very explicit.

Dan: we can ack the other use cases, but there's no way to only use it for the not-bad stuff.

Amy: one comment says that the alternative to going through with this is to just use anonymous iframe undconditionally. Best case from our perspective is doing this, right?

Peter: that's what I'd like us to say

Amy: there's a commit message that says there was positive signals from webkit and mozilla, and that anonymous iframe depends on coep reflection.. but anon iframe now decoupled

Dan: anonymous iframe removing dependency on coep is a good sign, anon iframe will exist regardless

Amy: mozilla, webkit .. responses are minimal

Peter: initially I had the same reaction - it's information you can already get so why not expose it. But if you think about it more and abuse cases, you start to get concerned

<blockquote> Hello folks. As things stand we're not convinced this is sufficiently in users' interest / addresses user needs. It looks to us like this circumvents privacy controls that are being introduced in the platform to the benefit of advertisers. There may be additional use cases as described by Mike above, but it's unclear how these could be enabled only for those non-ad use cases. Chromestatus still says no signals from Safari or Firefox. However we've seen some info from [Mozilla indicating support](https://github.com/mozilla/standards-positions/issues/645). However, it's not clear that they've considered the abuse cases as described above. So at this point we're leaning towards closing this issue with "unsatisfied" – unless there's some further info forthcoming. </blockquote>
Comment by @torgo Nov 14, 2022 (See Github)

Hello folks. As things stand we're not convinced this is sufficiently in users' interest / addresses user needs. It looks to us like this circumvents privacy controls that are being introduced in the platform to the benefit of advertisers. There may be additional use cases as described by Mike above, but it's unclear how these could be enabled only for those non-ad use cases. ChromeStatus still says no signals from Safari or Firefox. However we've seen some info from Mozilla indicating support. However, it's not clear that they've considered the abuse cases as described above. So at this point we're leaning towards closing this issue with "unsatisfied" – unless there's some further info forthcoming.

Comment by @ArthurSonzogni Nov 14, 2022 (See Github)

Thanks for your feedback. As a result of the w3ctag review, Chrome no longer pursuing COEP reflection. I think, we can close this.