whatwg / html

HTML Standard
https://html.spec.whatwg.org/multipage/
Other
8.03k stars 2.63k forks source link

Allowing top-level communication for cross-origin isolated documents #6364

Open arturjanc opened 3 years ago

arturjanc commented 3 years ago

The current model of cross-origin isolation is incompatible with federated sign-in flows based on popups. Any popup opened by a document with a COOP of same-origin will not be able to communicate with its opener, preventing passing information to the application to which the user wants to sign in (or, commonly, to the identity provider's iframe embedded by that application).

Some background for this decision is in https://github.com/whatwg/html/issues/3740#issuecomment-417469433 and the subsequent discussion.

Based on discussions with developers, it looks like this can become a barrier to adoption of cross-origin isolation and to efforts to enforce better isolation by default. We should give developers a recommended solution for this use case which will not require them to re-architect their applications to remove cross-origin isolation from parts of their application where the user is able to sign in.

The main difficulty is that due to browsers' efforts to disable the sharing of state across storage partitions, APIs which could have potentially been used as a fallback to allow the popup to communicate with its opener (BroadcastChannel, localStorage) are unlikely to be tractable approaches in the long term.

A few possible alternatives:

  1. Allow postMessage to be used in situations where COOP caused a browsing context group switch.
    • This seems awkward in the current design of COOP, but it would be the simplest approach from developers' point of view, because it wouldn't require changes to their client-side code. It also doesn't have cross-site tracking potential to the same extent as other "origin-wide" APIs, such as localStorage or BroadcastChannel.
  2. Build exemptions into the partitioning of BroadcastChannel to allow it to deliver messages between the popup and a same-origin iframe embedded by its opener.
    • This would require defining a set of criteria that would be met by legitimate scenarios (e.g. sign-in flows), but which would not allow BroadcastChannel to be used for cross-site tracking. My guess is that this is doable, but may be difficult to justify in a principled way, i.e. any partitioning exemptions would seem somewhat arbitrary.
  3. Ship WebID.

I do think that something like WebID could be a good long-term solution, but I'm worried that without a short/medium-term alternative we'll make life difficult for developers; an approach like (1) or (2) above could possibly be a reasonable alternative. Given the increasing interest in cross-origin isolation it seems somewhat important for us to figure this out soon.

/cc @annevk @mikewest @camillelamy Any thoughts or other ideas here?

annevk commented 3 years ago

I think I'm missing how postMessage() doesn't have the same tracking potential.

arturjanc commented 3 years ago

postMessage() lets you communicate only with a window to which you have a reference (or, possibly in this case, would have had a reference if it wasn't for COOP). The other mechanisms let you share data between all same-origin windows, even if they are in unrelated browsing context groups (possibly restricted by storage partitioning; but at the very least with same-origin windows in other BCGs with the same storage key).

So, hypothetically, in a browser without storage partitioning an ad iframe can synchronize state across all 3p contexts with BroadcastChannel or localStorage, but not with postMessage(). (FWIW this doesn't necessarily make a qualitative difference here; but I could imagine that from a cross-site tracking perspective postMessage() may be less concerning.)

davidben commented 3 years ago

@annevk I agree that postMessage has tracking potential for cross-site cases, but I don't think they're quite the same. In the long-term, I think WebID or something similar is the answer. However, in the short term, I think leaving federated auth at postMessage is preferable to moving it to BroadcastChannel. Tracking with BroadcastChannel requires the two top-level sites be open concurrently at all. postMessage at least requires the documents reach each other. To track, you'd need to either wait for that to happen (which we can hopefully reduce over time) or you'd need to, e.g., visibly open a popup. That's still not great, hence WebID, but I think it's meaningfully better than the BroadcastChannel version.

Moreover, in the long-term, same-(top-level)-site cross-origin documents also have communication uses. In those cases, neither postMessage nor BroadcastChannel have a tracking concerns. For non-broadcast versions of those flows, I think there are good developer ergonomics and performance (wake up fewer documents) reasons to prefer postMessage.

annevk commented 3 years ago

Apart from the tracking concern there's also an architectural concern as otherwise same-origin documents would now only have postMessage() as communication channel, supposedly. Not to speak of the impact on browsing context groups, less bfcache opportunities, etc.

arturjanc commented 3 years ago

I'm probably missing something, but I don't think this would prevent same-origin documents from using the other APIs to communicate, as long as they're within the same storage partition; e.g. top-level same-origin documents could still share data via localStorage, etc. The goal here is to additionally allow certain kinds of same-origin communication across storage partitions, which isn't disallowed by cross-site tracking protections (you still have direct DOM access to cross-partition same-origin documents), but which is disallowed by cross-origin isolation (because you can no longer postMessage() to your popup).

I'm also curious about the other kinds of impact you mentioned above, it would be helpful to understand these concerns.

What I'm worried about is that without providing COI documents with a recommended API to communicate with their popups, it's likely that developers will use alternative mechanisms to achieve the same goal, e.g. use link decoration in the OAuth popup to redirect back to a document in the application's origin and then use a mechanism like localStorage to exchange data. This is going to be more clunky and will possibly conflict with other cross-site tracking measures in the future.

annevk commented 3 years ago

Say A opens A' and A' has COOP and A' and A are same origin. Today that means A doesn't have a WindowProxy for A', with this, I guess it would. But somehow only postMessage() would be available? Today, A and A' do not share a browsing context group and therefore have independent agent clusters. With this, unclear? Today, WindowProxy references are never shared outside a browsing context group. With this, unclear?

arturjanc commented 3 years ago

Yeah, no disagreement from me here: this would certainly require figuring out a way to pass data around between BCGs intentionally separated by COOP. I guess my question is whether poking a hole for postMessage and allowing it to work across BCGs would be reasonable, or whether -- for example -- it's more appealing to make exemptions for BroadcastChannel to let it work across storage partitions in some cases (or implement WebID, or ...)

I realize that both of the ideas above can be ugly (or turn out to not be feasible), but my guess is that we don't do anything the workarounds built by developers are going to be much worse in the long run.

annevk commented 3 years ago

Personally something like WebID seems more reasonable to me long term, but I'm also interested in seeing workarounds that would work in Safari (assuming that Safari ships COOP soonish).

arturjanc commented 3 years ago

This is definitely a possible approach, but practically it will mean that -- until WebID ships in most browsers -- authors of OAuth flows will have to switch to one of the workarounds like link decoration + top-level same-origin sharing of state.

annevk commented 3 years ago

Well, we discussed OAuth flows while designing COOP and same-origin-allow-popups and unsafe-none were always meant for those use cases.

We also discussed allowing postMessage() and there were several implementation realities that made this infeasible (though I think for Firefox we're mostly past that now, including on mobile), but I also don't think we really tried to figure out what it would mean. And at this point I'd rather not add more tools to the popup workflow as they cause issues for anti-tracking and bfcache.

arturjanc commented 3 years ago

I don't want to belabor the point because I agree with you about the background and the difficulty here. But we do have more information today than we did a couple of years ago, which can have a bearing on our decisions. Specifically:

  1. Cross-origin isolation is gaining developer interest beyond what we (or at least I personally) expected, including ideas to enable it as the web default. We can't expect COI to be a niche thing for which developers are willing to jump through significant hoops.
  2. Anti-tracking improvements (storage partitioning) are removing mechanisms that were possible alternatives for this use case at the time we decided we can punt on postMessage support in COOP. Even if developers can still use workarounds (say, link decoration), it's likely that they aren't the right long-term approach and we shouldn't push developers in their direction.

Having postMessage work for the popup workflow actually seems like the most compelling option from an anti-tracking point of view. Anti-tracking efforts don't restrict postMessage with your popups; the fact that you can't use it from a COI context is an artifact of how we specced COOP, rather than being dictated by privacy considerations. It seems worthwhile to think about what workarounds developers will develop here (which I'm worried may be objectively worse from both a privacy and complexity point of view).

annevk commented 3 years ago

I think the fact that anti-tracking hasn't tackled popups (including postMessage()) yet is precisely because of OAuth making it hard, but everyone is well aware that they present loopholes that ought to be closed.

arturjanc commented 3 years ago

I have to say this is news to me; do you have a reference you could point to for this?

Also, I'd find this stance defensible if we had plans to break postMessage to popups from non-COI contexts, which doesn't seem like it's on the horizon? Otherwise we're just punishing developers who do the right thing and enable COOP+COEP.

annevk commented 3 years ago

Firefox has done some investigation here and I suspect we'll get back to it: https://bugzilla.mozilla.org/show_bug.cgi?id=1657250. It has come up in the Privacy CG a bunch too. And indeed that's why there is interest in WebID (though also wariness given the scope). (Saving grace of popups is that they require user activation, but that is not hard to come by.)

arturjanc commented 3 years ago

Thanks @annevk, this is helpful. Re: user activation, we could consider whether there are additional restrictions on the popup that would we could enforce to ensure anything we allow would only be usable for legitimate, i.e. non-tracking, use cases. For example, we could deliver messages only if the popup doesn't have a reference to any other window, require the popup to be same-origin with the document sending the message, etc (we'd have to be careful about this not causing an infoleak, but it should be doable).

My guess is that if we're planning to keep allowing postMessage() in non-COI contexts in the medium term, something like this could possibly be a workable interim solution until WebID or a better alternative ships. It wouldn't provide sites with anything more than non-COI documents can do already (and we could hopefully limit the scope, as mentioned above), and it could prevent the proliferation of workarounds that are more likely to conflict with upcoming anti-tracking work.

Zemnmez commented 3 years ago

I really think having postMessage broken with COOP is going to make it hard to implement for a lot of modern web applications, which have been pushed toward the greater security guarantees it provides vs historical approaches. I appreciate the nod to WebID, but there are plenty of cases where secure cross-origin communication is required that are not auth related.

mikewest commented 3 years ago

After a few conversations with @camillelamy and @arturjanc, I wonder if we could take an alternate approach to those proposed above by hardening COOP: same-origin-allow-popups until we considered it solid enough to enable cross-origin isolation (in combination with an appropriate COEP, just as today). If we could do that, we wouldn't need to break the window handle, and postMessage could continue to work, without asking developers to do additional work.

I think this hardening would boil down to allowing user agents to consistently process-isolate the newly opened window from its opener by breaking synchronous communication channels:

This seems like a path that might be worth exploring.

annevk commented 3 years ago

To be clear, even if the top-level window is cross-origin, that doesn't mean that all agent clusters "in that window" are. If A1 popups B and B embeds A2, A2 can reach A1 through parent.opener. So I think it all comes down to how you would solve for that. (And it sounds like the proposal is to change the keying for agent clusters, presumably coupled with changing IsPlatformObjectSameOrigin, which seems sound, but also breaks new ground as @domenic notes.)

(I guess there's a larger question here of whether we want to encourage this pattern given the issues with popups.)

mikewest commented 3 years ago

To be clear, even if the top-level window is cross-origin, that doesn't mean that all agent clusters "in that window" are.

Yes, I should have been more clear about that case, and I agree with you. I do think that changing the keying for agent clusters is a reasonable way of dealing with the issue, and I'm hopeful that this use case (which does seem like it's going to bite some folks trying to adopt COI) can motivate rekindling the conversation you're pointing to.

(I guess there's a larger question here of whether we want to encourage this pattern given the issues with popups.)

A related question is "How can applications that exist today adopt the security primitives we'd like them to adopt?" I think we're more likely to see more adoption if we can accommodate existing practice when possible. Paving cowpaths seems easier than asking the cows to hop into the Cow Transporter 2.0™ that we haven't actually figured out how to build yet. :)

mikewest commented 3 years ago

/cc @csreis, as he's concerned about the same issue Anne noted.

csreis commented 3 years ago

Yes, I'll mainly share that the example Anne noted happened in practice, at least in the past. In https://crbug.com/128772 from 2012, we found that Facebook was using an iframe on a cross-origin page to open a Facebook OAuth popup and expected script calls between the iframe and popup. That's a hurdle for putting OAuth popups in their own process (without OOPIFs and Site Isolation).

Caveat: I don't know if there are still sites doing that or if we have alternatives to recommend for them, but it's one of the cowpaths Mike mentions, and one that caused serious bugs in Chrome in the past.

hillbrad commented 3 years ago

I think that Facebook was historically responsible for most of these weird domain-lowered synchronous cross-frame/window accesses and that code should all be gone. I think cross-origin popups and iframes that break all sync relations but could use postMessage only to the opener keeps alive most important use-cases. It would even be fine to break the ability to traverse to other reachable contexts like opener.parent and the ability for the opener to navigate or do anything but close the popup reference.

domenic commented 3 years ago

@abflow, I'd kindly ask you to confine your suggestions for novel web security models to your own issues, and not comment on other people's issues with them.

camillelamy commented 3 years ago

One possibility could be to apply the restrictions only when COEP is enabled - i.e. create a COOP of same-origin-allow-popups-plus-coep which enables crossOriginIsolated. Then we can treat the fact that all frames enabled COEP as an opt-in into the restrictions. After all, right now a frame with COEP can be loaded in a cross-origin isolated context where its Agent Cluster is already keyed to origin. In this context, it cannot interact synchronously with a same-origin frame in a page with a different COOP status, because there are no pages with a different COOP status in the browsing context group. So, if we only impose restrictions when you have COEP, we wouldn't be breaking functionality, and sites would still have a way to make their OAuth flows work as long as it uses PostMessage.

arturjanc commented 3 years ago

@camillelamy Can you clarify what restrictions you are referring to above, i.e. are you talking specifically about the agent cluster keying changes?

I think the idea is reasonable, but I'm wondering if we'd need to care about the fact that COEP only applies to the opener's frames, but not to the openee's frames. Compare:

  1. A [COOP: same-origin-allow-popups-plus-coep] iframes B1, opens B2 [COOP: unsafe-none] as a popup.
  2. A1 [COOP: same-origin-allow-popups-plus-coep] opens B [COOP: unsafe-none] as a popup; B iframes A2.
  3. A slight variant of the above: A1 [COOP: same-origin-allow-popups-plus-coep] embeds B1, opens A2 [COOP: unsafe-none] which embeds B2.

In the first case, B1 must have opted in by setting COEP, as you say. In the other cases, COEP is only enforced on the iframes of the opening window and not the popup. I don't think this is a problem because keying of the agent clusters would prevent the top-level windows from sharing a process, I just wanted to make sure we consider this.

jyothsna commented 3 years ago

Not only Oauth flows, but also if there are front-end SDKs used by third party sites(A), then the SAB usage restrictions need to be hacked like the below. Page 2's purpose is solely to enable the cross-origin interaction via postmessage because siteA-page1 enabled COOP+COEP to use SAB. Site B is say some page related to the front-end SDK's company(say like a AWS SDK or Facebook SDK etc)

SiteA-page1(COOP+COEP) <--interact via local storage/broadcastchannel-> popup to SiteA-page2(no COOP) <--interact via postmessage--> Popup to SiteB(no COOP).

Is there a better way to avoid multiple popups as shown above?

camillelamy commented 3 years ago

@arturjanc I am talking about both changes.

Basically, the idea is that we create a new value of COOP, same-origin-allow-popups-plus-coep. This is set when a top level document sends a Cross-Origin-Opener-Policy: same-origin-allow-popups header and a Cross-Origin-Embedder-Policy: require-corp header. When a page has a COOP value of same-origin-allow-popups-plus-coep, its browsing context can be crossOriginIsolated if the user agent supports crossOriginIsolation.

In pages with COOP same-origin-allow-popups-plus-coep, agent clusters are keyed to origin. This is exactly like with COOP same-origin-plus-coep pages.

However, to make the crossOriginIsolation status of COOP same-origin-allow-popups-plus-coep work, we need to add one extra restriction. That is, documents whose top-level browsing contexts have different crossOriginIsolated status cannot have synchronous access to each other, and should only have access to the cross-origin WindowProxy methods. Maybe we can achieve that through keying agent clusters on crossOriginIsolated status as well, or maybe we need to add the crossOriginIsolated status as a parameter to determine if documents are same-origin or not (I am not really sure of the right way to spec this behavior).

My argument is that those restrictions are ok to apply to cross-origin subframes of the same-origin-allow-popups-plus-coep, because those subframes have set COEP require-corp. Which means that they have already opted into being loaded in a same-origin-plus-coep page, which has the following restrictions:

  1. Agent clusters are keyed to origin.
  2. Communication with documents in pages with different crossOriginIsolated status is impossible due to browsing context group switches.

So the restrictions we are putting on COOP same-origin-allow-popups-plus-coep pages are a subset of the restrictions in same-origin-plus-coep pages, which should be fine. Similarly, while documents in a popup opened by the same-origin-allow-popups-plus-coep page would not be able to interact synchronously with documents in the same-origin-allow-popups-plus-coep page, this is still better than no interaction at all in the same-origin-plus-coep page.

Basically, I think these restrictions should be ok when all cross-origin subframes have COEP, which is the point of contention for applying them to COOP pages without COEP. Since this would fix a major problem with the crossOriginIsolated rollout, I think this is a good direction for us to go in.

@jyothsna The proposal I am discussing above would simplify your example. You would have SiteA(COOP same-origin-allow-popups + COEP) <--interact via postmessage--> Popup to SiteB(no COOP).

camillelamy commented 3 years ago

Hey folks, I have put together an explainer for allowing COOP same-origin-allow-popups + COEP to make pages crossOriginIsolated. @annevk @domenic I'd appreciate your feedback!

annevk commented 3 years ago

Some thoughts:

  1. It seems Chrome is also pursuing WebID quite aggressively. Do we need both? As I mentioned above, I'm extremely wary of adding new functionality to popups.
  2. I don't see anything there about IsPlatformObjectSameOrigin.
  3. Do we want to expose the other non-postMessage() APIs?
  4. Is this even implementable in browsers without site isolation? (If I remember correctly we didn't do this for COOP exactly because of that concern.)
hillbrad commented 3 years ago

Re: (1), based on the recent workshop on WebID, my impression was that the proposals for more fully browser-mediated identity experiences intended to be options and recognize that the existing set of identity flows are diverse and may never be fully replaced. There are also many use cases beyond WebID that still rely on the popup pattern. More sophisticated OAuth2 permission and sharing dialogs (richer than what the WebID mediation based flows imagine), as well as things like photo pickers, friend finders, etc. that rely on the postMessage pattern, as well. It is a great way to provide a user-guided experience for selective sharing.

I'm less concerned about (3), and even would be OK with removing the ability to do address anything but e.g. window.opener or window.parent (no parent.parent or parent.frames[]) but completely removing the ability to do any async communications between a popup and its opener when opted-in to Spectre protections (which I expect will be essentially mandatory) is really damaging to a wide set of web platform abilities and patterns in broad use today.

On Mon, Jun 21, 2021 at 3:41 AM Anne van Kesteren @.***> wrote:

Some thoughts:

  1. It seems Chrome is also pursuing WebID quite aggressively. Do we need both? As I mentioned above, I'm extremely wary of adding new functionality to popups.
  2. I don't see anything there about IsPlatformObjectSameOrigin.
  3. Do we want to expose the other non-postMessage() APIs?
  4. Is this even implementable in browsers without site isolation? (If I remember correctly we didn't do this for COOP exactly because of that concern.)

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/whatwg/html/issues/6364#issuecomment-864930033, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAQVW4CNYFQEOI5PIRH35FDTT4JNBANCNFSM4XGIRJYQ .

camillelamy commented 3 years ago

@annevk

  1. Concerning WebID, I think both are needed. WebID is the right long-term solution for OAuth IMO. However, we also need a solution for people who need to deploy COOP now, and who cannot wait for their OAuth provider to switch to WebID. We have seen that dependency on 3d party changing their code is a big problem in the deployment of COEP, so if we have a solution that works with PostMessage, it would be simpler in the short term. The solution we're proposing has the advantage of working with other kinds of popup flows beyond OAuth, like payments.
  2. Ah my mistake. I was under the impression that the partitioning of Agent Clusters would achieve that. If it is not the case, beyond the partitioning we should also modify IsPlatformObjectSameOrigin to take into account crossOriginIsolated status.
  3. With the current proposal, yes. Basically, my goal is just to have documents with different crossOriginIsolated status be cross-origin, which means that they would have access to the cross-origin methods of WindowProxy.
  4. Because this applies to the whole page, yes. Since no documents on pages with different crossOriginIsolated status can ever be same-origin, we can put the two pages with different COOP status in different processes, event without SiteIsolation.

In terms of adding new functionality to popups, I don't think this is necessarily what we are proposing. The popup itself, which has to have COOP unsafe-none, gains no new functionality. It is the opener, which gains functionality (the ability to access COI APIs like SABs), at the cost of new restrictions.

comp615 commented 3 years ago

Great to see the discussion here! I just wanted to throw on a +1 and appreciation from the Twitter-side on this. We were just working on both cross-site isolation and Oauth SSO at the same time and saw the two worlds collide here. Because we're a single page app, it's somewhat inconvenient to force a reload with non-isolated (allow-popups) headers when a user needs to login; we'd love to just always provide secure headers. So we're very in favor of same-origin-allow-popups + COEP providing isolation as long as it can be done securely. Thanks for the rigorous thought here!

hemeryar commented 2 years ago

I spent some time inspecting all the cross references to same-origin and same-origin domain in this spreadsheet: https://docs.google.com/spreadsheets/d/1e6LakHSKTD22XEYfULUJqUZEdLnzynMaZCefUe1zlRc/edit This should help identify what in the spec should be updated if going forward.

Already known issues:

  1. Agent cluster keyeing needs to take into account crossOriginIsolation.
  2. IsPlatformObjectSameOrigin needs to take into account crossOriginIsolation.

Other issues:

  1. Javascript: navigations. They are currently behind the same-origin policy and I think these should be gated by cross-origin isolation as well. Otherwise an exploited page with origin A without cross-origin isolation could execute arbitrary javascript in another crossOriginIsolated page with origin A.

  2. Window.location API. It is available cross-origin but a number of members are gated by the same-origin policy. Things like window.location.origin getter or assign(). I think these should be gated by crossOriginIsolation as well as this could cause important information leakage.

  3. Named targets. BrowsingContexts can be targeted by names, and specific rules apply: https://html.spec.whatwg.org/multipage/browsers.html#valid-browsing-context-name-or-keyword The concept of "familiarness" is affected by the same-origin policy. I don't think this is an issue as it does not look much different to href setting.

Do my points above sound reasonable ?

annevk commented 2 years ago

It seems cleaner if IsPlatformObjectSameOrigin takes agent clusters into account. (This is pretty much a design goal, but until now it didn't need an explicit check as nothing else made it observable. To be clear, it's equivalent to what you suggest.)

Once that's done, I don't think the Location members can be accessed across the boundary. It seems you should only be able to get to the href setter and the replace() method and nothing else.

Named targets can result in opener getting set on targets. I think that's probably okay although I wouldn't mind clamping that down more and solving #313.

annevk commented 2 years ago

Also, if we care about information leaks, reducing what objects and properties are exposed across the cross-origin isolation boundary would still be good. Sites can infer quite a bit of information by enumerating frames and such. (It would be great if we could do this for A embedding cross-origin B as well where both have cross-origin isolation but are cross-origin, but that might no longer be compatible.)

hemeryar commented 2 years ago

Thanks for the prompt feedback Anne!

Just curious about the Location interface, if we apply both same-origin and IsPlatformObjectSameOrigin does that mean we're explicitly saying it should be "same origin" and not only "same-origin domain"?

About the opener relationship, I don't think that's an issue since we were already conserving the opener anyway (via Cross-Origin-Opener-Policy: same-origin-allow-popups), and this opener is already across Cross-Origin Isolation boundaries with this proposal. I do think issue 313 needs clarification, but seems outside the scope of that change. From what I can see (and experiment in both Firefox and Chrome) it's pretty much: "the user agent determines that the two browsing contexts are related enough that it is ok if they reach each other".

About information leaks, I also think we're ok with having these exposed since they were also exposed by the original COOP: SOAP. Use of SAB or memory measurement, etc. shouldn't really increase the dangerosity of exposing frame counts for example.

annevk commented 2 years ago

I'm not sure I understand the question about Location. If you have COOP+COEP document.domain cannot be used and origins are used to key agent clusters. So yeah, same origin-domain ends up not mattering as much.

As for opener stuff, there's a deterministic answer to "familiar with" that uses BCGs + some logic as scope, but yeah, it needs work. The reason to consider it would be to not allow reaching deeply into a COOP+COEP tree structure from the outside.

As for information leaks, I'm not sure how the comparison with COOP: SOAP works (assuming that's same-origin-allow-popups) as that doesn't allow for SAB.

hemeryar commented 2 years ago

Hey Anne!

Sorry I think there was some confusion in the previous discussion, I’ll start with the last point to clarify what I meant.

As for information leaks, I'm not sure how the comparison with COOP: SOAP works (assuming that's same-origin-allow-popups) as that doesn't allow for SAB.

Having COOP: same-origin-allow-popup-plus-coep enable crossOriginIsolated is what I was referring to in my previous messages as it was the most up to date proposal and the one I’m working on. In that context we already preserve the opener, and we already have access to side channel information. My point was that I don’t think having crossOriginIsolated capabilities would mean being able to abuse this information in any additional way.

As for opener stuff, there's a deterministic answer to "familiar with" that uses BCGs + some logic as scope, but yeah, it needs work. The reason to consider it would be to not allow reaching deeply into a COOP+COEP tree structure from the outside.

About “familiarness”, the definition I found was here: https://html.spec.whatwg.org/multipage/browsers.html#familiar-with and my guess is that it predates Browsing Context groups and was not updated. It looks like it is trying to redefine a BCG but with some differences. In particular it makes all same-origin Browsing Contexts familiar, which would mean reaching out to popups disowned because of COOP. In practice that’s not the case (both in Firefox and Chrome, we spawn a new window.). That avoids issues with the already existing COOP: same-origin-plus-coep value. However, for COOP: same-origin-allow-popup-plus-coep, we already preserve the opener, so we would already be able to target the entire tree. I believe manual disowning is an issue, but only a tangential one.

With all above considered, that would leave us in a state where if you have to you would use COOP: same-origin-allow-popups-plus-coep, and otherwise COOP: same-origin-plus-coep to also prevent side channel leakage, while in both cases getting crossOriginIsolated capability.

I'm not sure I understand the question about Location. If you have COOP+COEP document.domain cannot be used and origins are used to key agent clusters. So yeah, same origin-domain ends up not mattering as much.

Finally, about the Location interface: I was only wondering why it was the only place (as far as I can tell) where we explicitly add same-origin checks, while other interfaces rely on their integration with the IDL and a call to IsPlatformObjectSameOrigin(). But anyway that’s only out of curiosity, as mentioned crossOriginIsolated disables document.domain, so if there was any subtle difference it would not apply.

What do you think ?

hemeryar commented 2 years ago

Friendly ping in case this got lost :)

annevk commented 2 years ago

What's new with "allow popups" for isolated contexts is that a non-isolated context can now get the frame count of an isolated context. That's the part that seems a bit questionable. There's now also name targeting from non-isolated contexts into an isolated context. (Familiar with indeed needs redoing: #313.)

We used to have the isolated bit on a browsing context group, but this is essentially undoing that to some extent. (I haven't looked at the PR to see if it refactors that.)

Only Location and WindowProxy can be accessed across sites. I'm pretty sure the origin checks on Location are there in case you hold a getter/setter and use it on a Location object from another site. That is, IDL's perform a security check guards access, but not invocation. Not a 100% on this though, it's been a while.

hemeryar commented 2 years ago

Thanks for the PR passes Anne!

What's new with "allow popups" for isolated contexts is that a non-isolated context can now get the frame count of an isolated context. That's the part that seems a bit questionable. There's now also name targeting from non-isolated contexts into an isolated context. (Familiar with indeed needs redoing: #313.)

I see two directions we can go:

I personally think the second direction is a more elegant and maintainable path forward.

We used to have the isolated bit on a browsing context group, but this is essentially undoing that to some extent. (I haven't looked at the PR to see if it refactors that.)

That’s correct, we’re completely removing that state. It always comes from the headers, or is inherited for subframes agent clusters.

Only Location and WindowProxy can be accessed across sites. I'm pretty sure the origin checks on Location are there in case you hold a getter/setter and use it on a Location object from another site. That is, IDL's perform a security check guards access, but not invocation. Not a 100% on this though, it's been a while.

Sorry I'm not very JavaScript savvy, is that because of document.domain modifying the origin between grabbing the getter/setter and actually calling it? In that case that wouldn’t apply because of cross-origin isolation implying origin keyed agent clusters which in turn disables document.domain. Or is there some shenanigans where you can reapply a getter to another object or something like that?

annevk commented 2 years ago

Or is there some shenanigans where you can reapply a getter to another object or something like that?

Yeah, with .apply() or .call().

I think I agree with your other point, though I'm not enthused about it.

hemeryar commented 2 years ago

Yeah, with .apply() or .call().

Then I think we also need to update the location interface security checks to account for cross-origin isolation. I'll update the PR accordingly.

annevk commented 2 years ago

I see, we better add some tests for those cases to be sure. However, similar concerns apply to the #313 case, no? There's same origin checks there too.

hemeryar commented 2 years ago

I have updated the chromium WPT CL linked in the PR with an additional test covering the 19 gated access to location properties.

Regarding #313, as discussed above, all we can do is set an opener and navigate the frame, both of which are possible by directly grabbing the Window object or using the location.href setter. We also don't need to explicitly update the spec because it says that what we do is implementation defined. However if you'd prefer to have this stated explicitly I can add it in the definition of "is familiar with".

Currently, it is the browser responsibility to avoid being able to navigate a cross-origin isolated tab with origin A from another non isolated tab with origin A, including to javascript URLs and fully exploiting gated capabilities. Luckily, no browser allows that, and the PR restricts the use of javascript: URLs. That would probably not be a bad idea to spell out that specific case the spec though.

rniwa commented 2 years ago

@cdumez

annevk commented 2 years ago

During the XSLeaks conference we came up with another model that would allow for top-level communication, but in a way that would not overload COOP further.

The idea was to instead restrict WindowProxy access (and named targeting), potentially to closed and postMessage(). This would also need to apply to nested documents. If sites use that as well as COEP we could give them cross-origin isolation. Importantly this would address this use case, but it would also address the use case of popup endpoints not being able to isolate themselves. This idea is a lot less fleshed out, but I think it has potential as it addresses a whole set of problems we have been having. Apart from the use cases listed, it also protects parent and nested documents better from unwanted interference.

camillelamy commented 2 years ago

We have discussed this idea internally, and we think it has potential even without tying it to COOP or crossOriginIsolation. Especially as we can have it applied to nested documents as well.

To make it crossOriginIsolated, we would have to impose the same kind of restrictions regarding Agent Cluster scoping based on crossOriginIsolated status to make it something that can be implemented without Out-Of-Process Iframes. I think this is where a lot of the complexity of the COOP same-origin-allow-popups-plus-coep proposal comes from, so I am not sure that adding another policy which would also make things crossOriginIsolated would reduce the complexity that much.

annevk commented 2 years ago

The difference since then is that I think all engines now have the ability for "out-of-process tabs" as well as enough infrastructure to still make postMessage() work. So yes, this would have to impact agent cluster keying, but I don't think that's a problem. And I don't think this would be a reduction in complexity per se, but it would solve a greater set of problems people are having with COOP+COEP as well as other related problems.

camillelamy commented 2 years ago

So I think that we are in agreement that we want to bring a sort of Cross-Origin-Window-Proxy-Policy, I am not just sure whether it should enable crossOriginIsolation as well.

One interesting aspect of the discussion was the ability to have this policy explicitly spell out the authorized WindowProxy methods. As we try to move the web towards more isolation by default, I think this would be an interesting mechanism to restrict the use of less used WindowProxy APIs by default in a gradual manner. If we go in that direction, are we fine with this being sufficient for enabling crossOriginIsolation? Do we require a minimum of APIs to be disabled? I know that access to WindowProxy APIs was a contentious point during the design of COOP same-origin-allow-popups-plus-coep.

From a process perspective, the keying of agent clusters on crossOriginIsolated status when the top-level document has COEP is the necessary condition to support crossOriginIsolation without OOPIF (in the out-of-process tab model). So COOP is not technically necessary per-se. However, it does protect against WindowProxy accesses that could be more problematic in a more privileged context.