-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Allow Browsing Contexts to maintain opener member across Browsing Context Groups. #7713
Comments
To stress, the idea here is that this is the only "direct" relationship these BCGs would have. Named targeting, agent clusters, and other things scoped to a BCG would continue to be scoped to it. (Of course, if unrelated BCGs host same-origin documents those could communicate through storage-key-based APIs and that would not change.) Additionally, a BCG with this policy would have exactly one TLBC for its lifetime. All created popups result in a new BCG, potentially with a "direct" relationship. (I personally rather like the idea of making this Edit: note that if we have to swap a BCG with opener, we have to move that opener to the new BCG (unless COOP prevents it). Otherwise it likely wouldn't be viable for a popup service to adopt this policy since it might have to redirect to other sites that haven't yet migrated. |
Update on this, we're going to go for the COOP:Popups variant. I have drafted an explainer and will begin working on a spec PR. Updated the main post. |
Hey @hemeryar, thanks for putting a bunch of work into this! I had a rather open-ended discussion with @mystor and @smaug--- about implementation feasibility and potential alternative approaches which I'd like to summarize here and get your perspective on. One thing that came back a few times was if there is a way to solve this without relying on Now apart from that, a scenario @mystor brought up that deserves further scrutiny is this:
We end up with a situation where neither site.example nor (popup) embed.example have the policy, but they are also in separate agents. And thus site.example's embed.example and popup embed.example do not have synchronous script access to each other, whereas auxiliary.example adopted the policy they would have had that. Is that desirable? The alternative solution here is what we discussed earlier (and I argued against as it's also messy, but I didn't consider the above scenario), in that instead we introduce a boolean on the top-level browsing context which when true indicates that agent cluster lookup happens on a different map bound to that top-level browsing context for the duration of the boolean being true. That boolean would also be checked by WindowProxy and Location members to suitably restrict them (as well as discard incoming proxied messages). And it would be checked by named targeting which would bypass such top-level browsing contexts. With this kind of setup only embed.example when embedded through auxiliary.example would end up in its own agent. The remaining two (embed.example embedded by site.example and popup embed.example) would end up in the same agent and have script access. As I understand it this would be "simpler" to achieve, but it also would be more web compatible as only sites that opt-in notice the impact from the policy change. |
Thanks for the comments @annevk ! On the second, let's call that having "dynamic clustering", that is indeed the intended behavior. I think it is consistent with other COOP values, where for example the opener is not restored if you have:
Regarding the proposed solution, we'd get "dynamic clustering" for unsafe-none pages only, and not policy setting pages. For example:
I think both have their logic, although I still think since we're going for a COOP policy, keeping the same type of behavior makes sense. Let me know what you think! |
re: dynamic clustering: I agree with @hemeryar. While the behavior is a bit confusing, I agree it is similar to the general trickiness around redirects with COOP which is something we've generally found to be surmountable when rolling out COOP. And at least to me, it would be surprising if this new COOP value behaved differently in this respect.
Speaking very broadly, I know of 3 common use cases for interacting with popups:
So to summarize:
Footnotes
|
@hemeryar I'm a bit confused by your reply. Perhaps we should try to talk it through in person again.
I thought that was the plan regardless? That this new policy would always "isolate" you so popups could always run in parallel, even if everything in the popup was the same as you (origin, policy, ...). Also, I thought a problem with COOP for popups was that it breaks these opener relationships. This would allow preserving them better, no? In particular, if your authentication flow involves multiple parties as it might with corporate customers, not all of those parties might have adopted the policy and getting them to all adopt the policy at once would be hard. @ddworken thanks for the context. That does suggest to me we're stuck with |
Hi @annevk , I'm open to discussing in person again if that gets too confused here :) About the first point, I thought the initial plan was to key on origin, top-level origin, coi and policy value. So if two pages were same-origin AND same COOP:Popups, they could theoretically communicate synchronously without issue. I think we weren't on the same page here. If we go for the isolation boolean, we go for something working quite differently from previous COOP values. In particular a website would more or less lose the ability to communicate same-origin with a popup with anything else than postMessage(), because if either the opener or the openee has COOP: Popups we lose that capability. So that could be confusing in that sense.
An advantage with this policy is that since it only restricts the opener, as long as the interactions happen via postMessage it will be fine. We don't have something like COOP: Same-origin in the middle completely breaking the link and ruining it for further navigations. |
@hemeryar I don't really see how you thought that would be possible given they would have different BCGs (and thus different agents). That would be more of an option with a single BCG + TLBC flag, but I'd prefer giving the browser more flexibility in terms of process allocation if possible. |
@annevk Yes I'm talking about the initial solution with everything in a single BCG and a WindowPolicy. We discussed back then having the same agent cluster for pages with similar policies and origin. Regarding how easy the BCG opener vs the BC boolean would be to implement in Chrome, I'm not entirely sure. I've reached out to the Security Architecture team to discuss. So to sum up: Option A, opener across BCG:
Option B, an "isolate" boolean on BC:
|
@hemeryar for A we do need to change IsPlatformObjectSameOrigin, right? To account for "same agent". That previously was not a possible scenario, but now it somewhat is. (In a more ideal setup we'd more fully explain the objects and thus you couldn't end up with this weird corner case, but we don't have that.) I also don't understand what you mean with "(in)consistent with other COOP values". Those would break opener relationships across origin boundaries. Presumably that is not a thing we want here? E.g., when I use Google Accounts for my corporate account I end up using at least one cross-site-non-Google-controlled domain. Presumably it would be bad if that ended up breaking the relationship. |
@annevk Regarding how to achieve the actual restriction of properties for A, in the PR I simply added a line in About the consistency between COOP values, what I meant is that today, setting COOP on any Oauth does break the link forever as well, and COOP: Popups would do the same. On the other hand COOP was not designed to be put on popups in the first place. So I guess it could make sense to have a different behavior here. If you think that would be a big blocker to deployment in the wild, I'm happy to change the spec to have the BC boolean implementation instead :) I think one important thing to discuss is whether it would be expected to have two same-origin same-COOP page and popup not be able to have full access to each other. Maybe coming back to having another policy would be the better choice in that case? Doing exactly what's been described here, but having a different name to make it explicit that it behaves differently from other COOP values. |
A bunch of discussions happened offline that I want to sum up:
In any case, I think we can close this particular proposal as it is not relevant anymore. |
( Somewhat related to this discussion is something I discussed with annevk and mystor about openerPort which would be preserved through new page loads. One could pass a MessagePort to window.open, yet keep using noopener. The opened window would have openerPort property for communication with the opener. The two windows would still live in separate BCG and could use whatever COOP they want. That would be a new thing and require minor opt-in (communication through openerPort and not opener) ) |
We worked out in #6364 what became the COOP:Popups proposal. Implementing that requires preserving limited scripting capabilities between Browsing Context Groups to avoid overwhelming the agent cluster keying with many new members (like top level origin, window policy, etc.)
The following summary looks at how we'd achieve that:
Acronyms
BC: Browsing Context
BCG: Browsing Context Group
COOP: Cross-Origin-Opener-Policy
Related Browsing Context Groups
What makes a BCG hold all the possible scripting links is simply the fact that creating a new BCG does not update the new BC’s “opener BC” member. This is only done when “creating an auxiliary browsing context”. Therefore the opener getter returns null. There is no fundamental restriction to cross-BCG scripting other than that. From the window.open caller side, we do not get a reference due to the window type “no opener” in the open algorithm step 13, or the immediately following navigation step that later swaps BCG.
Given that there is no fundamental limitation, an idea would be to have “connected” BCGs, for which we would keep the opener/openee. When calling a WindowProxy getter we would only allow complete access for BC’s in the same BCG, and only a subset otherwise.
What we need for that:
Add an “opener” parameter to “Create a new BCG”. If specified, we plug it into the newly created BC’s “opener BC” member.
Modify the “obtain a BC for navigation response” algorithm. Any new means of connecting BCGs would arrive here with some sort of parameter saying that we want to keep an opener. Then we simply plug it in the creation of the new top level BrowsingContext.
Update WindowProxy get and set, to verify that the browsing contexts accessing the properties are same-BCG, otherwise restrict to a list of authorized properties. Not super familiar with this part but probably something similar to COOP reporting checks (step 2).
Key spec links
BCG definition
Create a new BCG
Obtain a BC for a navigation response
Choose a BC by name (what window.open uses)
Quick audit of BCG references
https://docs.google.com/document/d/1tQihYjvkp9IqztlvHn-wYbiiSW8R04-ZP5RPlPgWBkM/edit#
The text was updated successfully, but these errors were encountered: