Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Severing a document's opener relationship regardless of origin #10373

Open
yoavweiss opened this issue May 29, 2024 · 28 comments · May be fixed by #10394
Open

Severing a document's opener relationship regardless of origin #10373

yoavweiss opened this issue May 29, 2024 · 28 comments · May be fixed by #10394
Labels
addition/proposal New features or enhancements needs implementer interest Moving the issue forward requires implementers to express interest

Comments

@yoavweiss
Copy link
Collaborator

yoavweiss commented May 29, 2024

What problem are you trying to solve?

Some origins can contain different applications with different levels of security requirements. In those cases, it can be beneficial to prevent scripts running in one application from being able to open and script pages of another same-origin application.

In such cases, it can be beneficial for a document to ensure it has a null opener, even if the document that opened it is a same-origin one.

It'd be great if COOP included a value that enabled that.

What solutions exist today?

There are no solutions today to solve this AFAIK.

How would you solve it?

By adding a no-opener-allow-popups value to the Cross-Origin-Opener-Policy header, that results in a null opener when calling creating a new top level travesable.

Anything else?

No response

@yoavweiss yoavweiss added addition/proposal New features or enhancements needs implementer interest Moving the issue forward requires implementers to express interest labels May 29, 2024
@yoavweiss
Copy link
Collaborator Author

/cc @camillelamy

@annevk
Copy link
Member

annevk commented May 29, 2024

It seems a bit unfortunate that the header starts with Cross-Origin-*.

Also, I find omit rather vague given the current values. Are popups allowed for instance?

@yoavweiss
Copy link
Collaborator Author

Also, I find omit rather vague given the current values. Are popups allowed for instance?

Maybe "noopener" would be a better value. From my perspective, popups should be allowed, as long as they have their opener relationship severed.

@yoavweiss yoavweiss changed the title An omit Cross-Origin-Opener-Policy value A Cross-Origin-Opener-Policy value that severs the opener relationship regardless of origin May 29, 2024
@yoavweiss yoavweiss changed the title A Cross-Origin-Opener-Policy value that severs the opener relationship regardless of origin Severing a document's opener relationship regardless of origin May 29, 2024
@annevk
Copy link
Member

annevk commented May 29, 2024

I think I understand what you mean, but that's a confusing comment given the current set of values. As in, same-origin-allow-popups explicitly does not break the relationship with any popups. It only breaks the incoming cross-origin relationship, if any.

To date we have only used noopener for outgoing relationships, but it might still be reasonable.

I think the other bit that's missing here is some kind of rationale as to why we would want to invest in this capability.

@yoavweiss
Copy link
Collaborator Author

I think the other bit that's missing here is some kind of rationale as to why we would want to invest in this capability.

Fair, I augmented the OP a bit. Let me know if that's sufficient to understand the motivation.

@annevk
Copy link
Member

annevk commented May 29, 2024

I think that justifies incoming but not outgoing. It also raises some other questions:

  • What about embedding?
  • What about channels that are still available, such as storage, BroadcastChannel, shared workers, etc?

@yoavweiss
Copy link
Collaborator Author

I think that justifies incoming but not outgoing

True. Thinking through this, I agree that it doesn't matter for the use case that outgoing opener relationships would be severed.

  • What about embedding?

CSP frame ancestors's value of 'none' allows sensitive apps to prevent themselves from being framed by other same-origin apps.

It's true that there may be cases where a frame may want to force itself to be sandboxed from the embedder. (in cases where it needs to be framed by some same-origin apps, but not directly scripted by them)

  • What about channels that are still available, such as storage, BroadcastChannel, shared workers, etc?

Those are presumed to be fine as communication between the different apps is permitted. (they are still the same origin)

@yoavweiss
Copy link
Collaborator Author

I think I understand what you mean, but that's a confusing comment given the current set of values. As in, same-origin-allow-popups explicitly does not break the relationship with any popups. It only breaks the incoming cross-origin relationship, if any.

To date we have only used noopener for outgoing relationships, but it might still be reasonable.

Changed to OP to propose the value to be no-opener-allow-popups. Let me know if that's clearer.

@yoavweiss
Copy link
Collaborator Author

After some prototyping, I'm now less certain that this can be achieved without an opt-in from the opener.

Given that window.open() is sync, and that COOP headers are received later on, it's unclear to me we can sever the relationship from the opener to the openee synchronously.

Maybe we can somehow severe it after the headers are received, but I'm not sure how that would look like without creating race conditions.

/cc @camillelamy @ArthurSonzogni

@annevk
Copy link
Member

annevk commented Jun 3, 2024

The opener would have a reference to a closed initial about:blank. That's the same as with COOP today, no?

@ArthurSonzogni
Copy link
Member

it's unclear to me we can sever the relationship from the opener to the openee synchronously.

A "frame" can't stand without a document. So when creating an <iframe> or a popup, they are both starting from the initial empty document. Creating the pair of frame and its initial document is always synchronous.

This is only after a subsequent navigation (always asynchronous) that we start receiving headers and can decide to instantiate the next document in a different browsing context group.

Maybe we can somehow sever it after the headers are received, but I'm not sure how that would look like without creating race conditions.

From the implementation or specification point of view?
Modifying ShouldSwapBrowsingInstanceForCrossOriginOpenerPolicy in your patch seems right. Hopefully, the COOP implementation can be reused.

@smaug----
Copy link
Collaborator

So how should this work if a new window is first opened with page A and then later navigated to B and only B uses the new header? The Window(Proxy) A (and B?) uses may have plenty of other references than the opener relationship at that point.

@yoavweiss
Copy link
Collaborator Author

So how should this work if a new window is first opened with page A and then later navigated to B and only B uses the new header? The Window(Proxy) A (and B?) uses may have plenty of other references than the opener relationship at that point.

I think that would be similar to the opener relationship when page A opens a same-origin B, which then navigates to a cross-origin document.

@yoavweiss
Copy link
Collaborator Author

I think that would be similar to the opener relationship when page A opens a same-origin B, which then navigates to a cross-origin document.

That's inaccurate. What I should've said is that it would be similar to the opener relationship when page A with a same-origin COOP opens a same-origin B with same-origin COOP, which then navigates to a same-origin document C with a unsafe-none COOP.

@smaug----
Copy link
Collaborator

ok, and how does "noopener" in the new value hint about that behavior? Isn't the change you want a tweak to https://html.spec.whatwg.org/#matching-coop so that in some cases that same origin check wouldn't be done (and nothing to do with noopener as such)?

@yoavweiss
Copy link
Collaborator Author

That's indeed what I did in https://github.com/whatwg/html/pull/10394/files

@annevk
Copy link
Member

annevk commented Jun 7, 2024

I think what @smaug---- is getting at is that he doesn't find noopener a clear name for severing the incoming relationship as it has thus far only been used to sever the outgoing relationship. However, I'm not sure what he would prefer instead. I personally find noopener[-allow-popups] much clearer than the initially proposed omit, but maybe there is something better?

@smaug----
Copy link
Collaborator

That, and also this feels like a distinct feature of COOP itself, just like the existing noopener is a feature of its own.

@yoavweiss
Copy link
Collaborator Author

Looking at the definition: "A cross-origin opener policy value allows a document which is navigated to in a top-level browsing context to force the creation of a new top-level browsing context, and a corresponding group"

That seems to be what we want here. Beyond that, we want to prevent the opener from being able to script the document in question. So to me, this very much feels related.

I hesitated a bit on the Report-only mode and how it translates, but after thinking about it, it does seem like something we'd want in order to facilitate deployment here (just like for COOP).

Happy to discuss this further :)

@smaug----
Copy link
Collaborator

But noopener itself is already a separate functionality in the platform. Is there a reason to not let opened page pages control opener relationship without binding that functionality to COOP.
I can see use cases, at least optimizations, for noopener without COOP. The page could that way try to optimize process usage in browsers, since they are more likely to use separate process when there is no opener relationship. And even more importantly bfcache requires noopener.

@annevk
Copy link
Member

annevk commented Jun 20, 2024

What additional functionality does COOP have? I thought this was it.

@smaug----
Copy link
Collaborator

smaug---- commented Jun 20, 2024

We discussed about this, and I can live with this. But this needs some documentation outside the normal COOP parts so that people trying to optimize for example bfcache handling can realize there is a way to break opener relationship also from openee side.

(Still feels like mixing two different features conceptually, when noopener from caller side is a separate thingie)

@annevk
Copy link
Member

annevk commented Jun 20, 2024

Why does that documentation concern not apply to COOP generally?

@annevk annevk added the agenda+ To be discussed at a triage meeting label Jul 1, 2024
@smaug----
Copy link
Collaborator

It does. But having something called Cross-Origin-Opener-Policy being possibly in a critical path on enabling bfcache even on same origin pages is a bit confusing.

@annevk
Copy link
Member

annevk commented Jul 1, 2024

I don't think this value necessarily helps with bfcache though? In particular it still allows the document to open its own popups, which would end up invalidating its cache entry as I understand it.

@smaug----
Copy link
Collaborator

Right, but you have the existing noopener for those cases.

@annevk
Copy link
Member

annevk commented Jul 3, 2024

I guess for bfcache the initial idea of noopener as a value that applies to incoming and outgoing would be quite useful then. If it's indeed the case that bfcache only works if your browsing context group only holds a single top-level browsing context at a time (which sounds about right).

@annevk
Copy link
Member

annevk commented Jul 5, 2024

So two things that came up yesterday:

  • As mentioned above having noopener as a value would be somewhat useful to be able to guarantee bfcache eligibility. cc @rubberyuzu @fergald
  • We need to figure out if this should relate to COEP. This seems somewhat tricky, but I do worry that if we don't explore it now we'll regret it later. cc @camillelamy

@past past removed the agenda+ To be discussed at a triage meeting label Jul 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
addition/proposal New features or enhancements needs implementer interest Moving the issue forward requires implementers to express interest
5 participants