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

Making postMessage() work for SharedArrayBuffer (Cross-Origin-Embedder-Policy) #4175

Closed
annevk opened this issue Nov 14, 2018 · 93 comments
Closed

Comments

@annevk
Copy link
Member

@annevk annevk commented Nov 14, 2018

#3740 (comment) sketches out v1 for the various headers needed to enable SharedArrayBuffer and friends.

At Mozilla we think we'll quickly need to address a need @arturjanc and @csreis hinted at. Being able to have cross-origin frames, either in the same process (e.g., because it's a process-contrained environment), or in a different process.

Our idea around this would be to add a new keyword to the Cross-Origin-Frame-Policy header:

Cross-Origin-Frame-Policy: same cors
Cross-Origin-Frame-Policy: same-site cors

If the cors keyword isn't set the v1 semantics apply, and cross-origin/site navigations result in a network error. If the cors keyword is set, the CORS protocol semantics apply to frame navigations. Judging from https://wicg.github.io/cors-rfc1918/ this could mostly be done through modifications to Fetch, which makes this less difficult than I initially anticipated. Navigations should also never require a preflight, therefore only requiring modifications to the final resource on servers (and redirects, if any).

A risk here for the embedder is that the embedded could redirect or navigate to an attacker. https://w3c.github.io/webappsec-cspee/ and sandboxing can be used to mitigate this, similar to how you'd combat XSS in your own document.

The short term advantage is that we could have something that works in all browsers more quickly, the long term advantage would be potentially saving on resource usage. And more speculatively this kind of trust relationship might also be beneficial to other APIs.

We'd like to implement this shortly after or together with v1.

Note that none of this has an effect on the WindowProxy/Location same origin-domain check. That will continue to consider such frames as being in a different origin.

cc @whatwg/security @rniwa @tomrittervg

@csreis
Copy link

@csreis csreis commented Nov 15, 2018

Thanks for proposing this! If I follow correctly, this would basically allow SharedArrayBuffer-enabled documents to load cross-origin iframes as long as the iframe requests use CORS (in the spirit of X-Bikeshed-Allow-Unisolated-Embed). This would imply that the cross-origin iframe's server would acknowledge that such data would be accessible to the embedding page, and thus it's safe to include in the same process even if SharedArrayBuffers or other precise time features make Spectre attacks more likely. (Meanwhile, browsers with support for cross-process frames could load such iframes in a different process without diverging in behavior from the user's perspective.)

I'm not 100% sure ad sites (etc) would go for this "full access" approach (where the embedding page could just as easily fetch the iframe URL and read its contents), but it does seem to make explicit that the data could be read with Spectre, and thus conveys the risks in a reasonable way. I imagine it might be sufficient.

I think this would resolve my main concern from the other thread (#3740 (comment)). @arturjanc, does this sound reasonable from your perspective?

Loading

@mikewest
Copy link
Member

@mikewest mikewest commented Nov 15, 2018

Navigations should also never require a preflight, therefore only requiring modifications to the final resource on servers (and redirects, if any).

For my own clarity, I think this is what you're proposing:

  1. The embedding document asserts Cross-Origin-Frame-Policy: cors.
  2. The embedding document embeds <iframe src="https://cross-origin.site/">.
  3. The browser requests https://cross-origin.site/, sending an Origin and
  4. If https://cross-origin.thing/ responds with Access-Control-Allow-Origin: https://embedder.site/ and Access-Control-Allow-Credentials: true, we allow the embedding. Otherwise, we return a network error.

Is that right?

It's not clear to me what capabilities this would expose. Like, does the embedder get DOM access to the embedee? That seems like something we'd want to avoid. As @csreis notes, this also seems to create the risk that page contents are directly revealed via fetch(), which also seems like something we'd want to avoid.

CORS-RFC1918 took a different approach, forcing a preflight, but not forcing CORS access to the page itself. That might be an interesting approach here as well, as it would reduce the risk that page content would be inadvertently exposed to an embedder by making it opt-in (via the preflight response), but not directly exposing the page data to the embedder (by not requiring CORS headers on the non-preflight response itself).

Loading

@annevk
Copy link
Member Author

@annevk annevk commented Nov 15, 2018

It's not clear to me what capabilities this would expose.

It mainly would allow for process reuse on process-constrained environments, as stated in OP.

Like, does the embedder get DOM access to the embedee?

See last paragraph of OP.

As @csreis notes, this also seems to create the risk that page contents are directly revealed via fetch()

It's not clear to me how much it's worth trying to distinguish that case from putting something in the same process. It seems it might give a false sense of security.

Loading

@arturjanc
Copy link

@arturjanc arturjanc commented Nov 19, 2018

For opt-in, I like @mikewest's preflight-based approach from https://wicg.github.io/cors-rfc1918/#shortlinks

This should allow the owners of cross-origin resources to respond to OPTIONS requests with something like Access-Control-Allow-Embed: true without also allowing direct reads of response contents via fetch(). I sympathize with the concern about giving server owners a false sense of security, but would prefer to avoid encouraging server owners to allow direct access to their responses (e.g. we don't want ad network resources to be directly readable via CORS since that would reveal interesting information about users).

There is a possibility that Spectre-like attacks would be able to exfiltrate the contents of the frame, but they would likely be less powerful and noisy; and, importantly, they wouldn't work against browsers with OOPIFs (whereas if we require regular CORS opt-in via Access-Control-Allow-Origin then we would expose the contents also in browsers with OOPIFs where introducing the leak isn't necessary.)

A benefit of this approach is that it would enable identical behavior across browsers: on pages with Cross-Origin-Frame-Policy all browsers would send a preflight on cross-origin iframe requests and would require the server to opt in. However, as browsers adopt OOPIFs the responses would become safe against exfiltration via speculative execution attacks, while still requiring the server to opt into embedding (which is okay because servers will have to do this in the short term anyway).

Loading

@arturjanc
Copy link

@arturjanc arturjanc commented Nov 19, 2018

Also, stepping back a bit, do we even need the same / same-site switch in this case? I think we can allow same-origin frames by default, and for any non-same-origin framing requests we could use the CORS / preflight approach to require resource owners to opt in. This would also be safer because we would prevent foo.example.org from declaring itself eligible to frame bar.example.org while getting access to high-res timers or other dangerous APIs, allowing it to potentially exfiltrate cross-origin contents from its sibling subdomain.

If we did this, then the header could just become Cross-Origin-Frame-Policy: 1 (or some other more descriptive name/value.)

Also, to push this idea as far as possible, could we even completely fold this into the Upgrade-No-CORS header? Then the header would require sending all non-same-origin subresource requests as CORS and do the same for iframes as discussed above. It would also have to apply recursively to all frames, but this should be okay because, as outlined above, servers would have to opt in or otherwise the frame would not be loaded.

I think this might be conceptually simpler for developers while giving us all the security properties we need for the L2 mechanism.

Loading

@annevk
Copy link
Member Author

@annevk annevk commented Nov 20, 2018

  1. If you don't do "true" CORS for navigations, I don't think it's reasonable for browsers to same-process these frames long term. That might be okay, but wouldn't be ideal for process-contrained environments.
  2. Upgrade-No-CORS is specifically named after Fetch's "no-cors" mode. Navigations use the "navigate" mode, which is similar, but different. Also, per your proposal navigations wouldn't use "true" CORS, they'd only preflight.

So I think I agree with your plan, but we need a new name for the header. Perhaps Use-CORS, with the explanation that for subframe navigations this means a specific kind of preflight only.

So, why not also use this approach for popups you want to cooperate with?

Loading

@annevk
Copy link
Member Author

@annevk annevk commented Nov 23, 2018

So while trying to explain this model to someone over lunch I realized this allows for escaping the "Use-CORS" restriction in browsers without process-isolated frames/popups.

attacker.example specifies Use-CORS and the correct opener policy. It loads collaborator.attacker.example in a frame/popup and that positively replies to the preflight. collaborator.attacker.example isn't restricted itself by CORS however can load all kinds of "no-cors" resources into the process.

It seems to me we need to require that collaborator.attacker.example also specifies Use-CORS.

Loading

@annevk
Copy link
Member Author

@annevk annevk commented Nov 23, 2018

I talked with @arturjanc, his assumption was that Use-CORS is inherited cross-origin in these cases, which is probably acceptable as the navigation response opted into it via the preflight.

Loading

@annevk
Copy link
Member Author

@annevk annevk commented Nov 23, 2018

Not discussed yet: if you restrict to same-origin, what are the implications for document.domain (also raised at #3740 (comment)) and SharedArrayBuffer? It seems those would not work then cross-origin, but same-site. It's not entirely clear to me if that's desirable. (It's ideal, but...)

Loading

@annevk
Copy link
Member Author

@annevk annevk commented Jan 4, 2019

I'm no longer entirely convinced we need the preflight.

  1. I'm worried it creates an unacceptable performance penalty.
  2. It doesn't seem to offer any additional protection. It was inspired by the local network proposal where it does make sense, but CSRF will remain a problem here and has to be dealt with differently.

I think instead the model should be such that once a browsing context group has its "Use-CORS" flag set, any resource navigated to within that group needs to have the Use-CORS header set. And if not, the network layer will return a network error. I'm not entirely sure if we should require redirects to have this header set or not. (A redirect can be navigated to if it doesn't have a Location header or the value of that header cannot be parsed. In that particular case it definitely needs to have the header set, but I'm less clear on when we simply follow it to somewhere else.)

Then, there's the question of credentials. Other than with fetch() (which defaults to "same-origin" for credentials), "no-cors" fetches will always include credentials across origins. So we need to at least support the equivalent of HTML's crossorigin="use-credentials" (this made me think that Cross-Origin: use-credentials as header might not be too bad). Whether we also need crossorigin="anonymous" is less clear, but that would allow for a less complicated CORS setup.

If we allow variance in credentials, it probably does not make sense to require it to match across documents. It's reasonable for different documents (esp. cross-origin) to have their own "no-cors" credentials policy.


For a moment I was worried about service workers and the cache API being able to introduce opaque responses into "Use-CORS" documents. However, this concern is probably unfounded. A service worker is handled by it not being able to return opaque responses to "cors" fetches (we'll upgrade before hitting the service worker). The cache API will need to be restricted from returning opaque responses in "Use-CORS" environments somehow. Currently you cannot do anything with such responses anyway in documents so maybe that's enough (assuming an implementation that leaves the bytes in the "storage process" until requested), but we'll need to be cautious going forward. An alternative is to prevent them from being returned altogether when the top-level flag is set.

Loading

@annevk
Copy link
Member Author

@annevk annevk commented Jan 4, 2019

When does Use-CORS/Cross-Origin take effect:

  1. It initially needs to be a on a resource that results in the creation of a new browsing context group. I.e., one that has Cross-Origin-Opener-Policy set.
  2. To be clear, this Cross-Origin-Opener-Policy requirement doesn't apply to further navigated resources loaded in that browsing context group. For those only this new second header matters (except for top-level browsing context navigations with a non-matching Cross-Origin-Opener-Policy).

As for document.domain:

  1. The simplest thing to do I think is to continue to allow document.domain and to continue to key agent clusters on sites. Same-site resources can only be attacked if they opt in via CORS or this new second header though (assuming they're navigable).
  2. The ambitious thing to do is to require Cross-Origin-Opener-Policy: same-origin ... when using this new second header and change the browsing context group's agent cluster keying such that the key is now origin, effectively disabling document.domain. Unless folks are particularly motivated to do this exercise, this seems unlikely to happen. Attempts at making document.domain worse in the past have largely failed and tightly coupling the worsening with important new features puts the new feature at risk.

Loading

@annevk
Copy link
Member Author

@annevk annevk commented Jan 8, 2019

A thing we haven't really discussed or at least written down in these threads is how SharedArrayBuffer is enabled. I propose that SharedArrayBuffer is always there, but only agent clusters with a flag set allow it to be messaged between agents. This means that the ECMAScript standard can continue to say it's always exposed and HTML (the host) will impose the limitation on usage. By not allowing it to be messaged it's effectively equivalent to and no more dangerous than ArrayBuffer.

Making StructuredSerializeInternal throw ("DataCloneError") when it's invoked in an agent cluster that wasn't created under the right circumstances should be sufficient for this I think.

Loading

@annevk annevk changed the title Cross-Origin-Frame-Policy v2, enabling cross-origin frames Opting into a CORS-only mode (Cross-Origin) Jan 18, 2019
@annevk
Copy link
Member Author

@annevk annevk commented Jan 18, 2019

Feedback and attempts to address it:

  • How do sites know about being included? I think we should reuse the Origin header here. This already works for CORS, it seems fine to reuse here. As Origin is used for CORS purposes, Referrer Policy cannot affect it (for subframe and popup navigations). Currently Origin is not included for GET navigations, so this should work I think (and server-side needs changes anyway due to the response headers).
  • Should we require X-Frame-Options? This was suggested as Cross-Origin would be used for all responses so if you don't consider the possibility of being framed, someone might end up framing you. It seems somewhat reasonable, but I'm a little wary of adding this additional complexity. (Remember that currently Chrome requires none of this.) We don't have to add allow from * necessarily as you could echo the origin value after allow-from (similar to what we require with CORS). Potential issues:
    • same-origin is spelled sameorigin (case-insensitive too) and there's no same-site as we have elsewhere.
    • There's an equivalent feature in CSP. Would we also make that work and increase the complexity even more? I'd hope not.
    • I think there are some interoperability issues around allow-from.
  • Does Cross-Origin work in a browsing context group without Cross-Origin-Opener-Policy? Nika argued that it should and apply to the subtree. I think that's fine. We do have to be careful here with what other APIs build on top of this as this isn't necessarily a secure primitive (i.e., nothing should prolly be build on top of this). It would mainly give consistency in loading resources.

Loading

@annevk

This comment was marked as off-topic.

@annevk

This comment was marked as off-topic.

@csreis

This comment has been hidden.

@jakearchibald
Copy link
Collaborator

@jakearchibald jakearchibald commented Feb 8, 2019

Can a Use-CORS page contain an iframe to a cross-origin page that doesn't have Use-CORS? What happens if a SharedArrayBuffer is postMessaged to the iframe?

Update: BroadcastChannel and the service worker clients API creates the same problem with same-origin pages.

Loading

@annevk
Copy link
Member Author

@annevk annevk commented Feb 9, 2019

https://gist.github.com/annevk/17f580379c45802d5c3aef5a8fd53c7d has more details on the processing model. Feedback welcome!

@jakearchibald the iframe case would result in a network error for the frame. BroadcastChannel does not pose a problem as those pages would be in different agent clusters (they'd get the messageerror event). Service workers are also in their own agent cluster.

Loading

@clelland
Copy link
Contributor

@clelland clelland commented Feb 21, 2019

Edit: Updated link

I'm wondering if it would be possible to extend this with a mode which simply set all fetch requests' credentials modes to 'omit', without also upgrading to CORS?

Cross-Origin: omit

This could allow sites to adopt the Cross-Origin header to enforce that they do not ever request any user-specific data from third parties, but would still be able to link to anonymous public resources, cache images and scripts on CDNs, and preserve the more-or-less free embedding that the web has always had.

I had written up a proposal along those lines here a few days ago, which seems very similar in spirit to this.

Loading

@csreis
Copy link

@csreis csreis commented Feb 22, 2019

Thanks for mentioning, @clelland! I think the credential-less mode is worth considering, as it would allow sites to pull in effectively public third party subresources without needing CORS on them, and thus impose fewer restrictions without giving up much of the security value. (Presumably documents could optionally request credentialed subresources with CORS if they wanted them.) I also imagine that would be easier to eventually enable by default than CORS-only, and using it here for enabling precise timers might be a step in that direction.

The main hole is probably intranet resources, but maybe something like RFC1918 can help (cc @mikewest)?

What are others' thoughts on full CORS vs credential-less requests?

Loading

@csreis
Copy link

@csreis csreis commented Feb 22, 2019

Adding @bzbarsky and @ehsan, who brought up similar ideas about a credential-less mode (or default) in the past. Requiring it to enable precise time (perhaps instead of CORS for all cross-site subresources, as we've been discussing here?) might be a nice step towards making credential-less subresources be the default, which would help cover the cases CORB misses today.

Loading

@annevk
Copy link
Member Author

@annevk annevk commented Jun 19, 2019

I'm okay with both of those suggestions, with a slight preference for CO-Embedder-P over CORUP. (Though to be fair, there's probably a lot of names Mozilla could be comfortable with at this point.)

Some initial feedback on the document:

  • Issue 1 seems placed incorrectly. My feedback was about a valid embedder policy and an invalid resource policy. To me it seemed that allowing the resource to be more than same-origin in that case would enable side channel attacks in user agents that don't yet support the new syntax.
  • It should use https://fetch.spec.whatwg.org/#concept-header-list-get to get the header value. (I'm happy to add "get and decode" if you'd prefer operating on strings.) You'll also need to account for there not being a value.
  • "If header matches the sh-token grammar" I don't think this is needed or something we expect implementers to do. The idea should be to get the value, then parse it.
  • I don't think we need "creator embedding policy" as persisted state since we directly set it on the document when creating the browsing context and there's nothing else that needs it as far as I can tell.
  • For dedicated workers we need to enforce that the flag is set (or force inherit it) as they end up in the same agent cluster (and the same browsing context group which is the theoretical process boundary (and practical in some deployments) for the purposes of COOP and COEP).
  • "We might not need to inhert the COEP state into auxiliary frames" I think we have to if we want to allow SAB in combination with unsafe-allow-outgoing.
  • As for inheritance vs requiring the header (issue 4), note #4175 (comment). I'm not sure I entirely agree with that still as if they don't set COOP they won't get SAB when loaded in a top-level. And if they don't set COEP they get different fetching behavior when loaded in a top-level which is also confusing. So slight preference for requiring COEP.
  • As for shared/service workers: COEP there is useful to enable SAB in those contexts. If an implementation wants to put a shared/service worker in the same process as a same origin document with COEP/COOP, the shared/service worker will need COEP, as otherwise the document could use a shared/service worker for attacks. From a specification perspective a shared/service worker creates its own agent cluster and can be process-separated from the rest and Mozilla has been assuming thus far that this is a possibility for all implementations.

Loading

@mikewest
Copy link
Member

@mikewest mikewest commented Jun 20, 2019

s/Cross-Origin-Embedding-Policy/Cross-Origin-Embedder-Policy/

Done in WICG/cross-origin-embedder-policy@a7433c5 (but I think we'll probably revisit this, as both seem ambiguous! :) ).

Issue 1 seems placed incorrectly.

Then I think I misunderstood your feedback. Let me try again: CORP currently fails open in the face of an unknown value. You're suggesting that if this flag is set, we should instead fail closed. I think I can accept that conceptually, but would suggest that there are extensions to CORP (whatwg/fetch#760 in particular) that I'd really like to get in before we lock it down. If we don't, I think it's going to be much more difficult to ship those extensions, and I think that would make me sad.

It should use https://fetch.spec.whatwg.org/#concept-header-list-get to get the header value.
...
"If header matches the sh-token grammar" I don't think this is needed or something we expect implementers to do.

It would be nice to clarify the integration between Fetch's concept of headers, and the algorithms in https://tools.ietf.org/html/draft-ietf-httpbis-header-structure. I'm attempting to use the parsing algorithm defined in Section 4.2, and I'm not really sure where @mnot, et al envision this processing happening and whether the requirements actually mesh. For example, the parsing algorithm requires ASCII, while I'm pretty sure Fetch doesn't. In any event, I think you're right, Anne, that I should grab the header from the header list and parse it as text: WICG/cross-origin-embedder-policy@ec62f6d

I don't think we need "creator embedding policy" as persisted state

Got it: WICG/cross-origin-embedder-policy@4ad7dab (I think we might be able to drop "creator referrer policy" as well?).

For dedicated workers we need to enforce that the flag is set (or force inherit it)

I think this is what the document currently says (in the first block of step 3 of https://mikewest.github.io/corpp/#initialize-embedding-policy-for-global).

"We might not need to inhert the COEP state into auxiliary frames" I think we have to if we want to allow SAB in combination with unsafe-allow-outgoing.

Wouldn't unsafe-allow-outgoing create a new browsing context group for the auxiliary window?

As for inheritance vs requiring the header (issue 4) ... slight preference for requiring COEP.

I agree, and I think this is where @arturjanc and @yutakahirano came down as well. It seems marginally safer for the document to explicitly opt-into the whole mechanism. That also seems marginally more complicated for developers to adopt. We also suggested that it's easier to take restrictions away in the future than to add them ex post facto.

I think this will require changes to the navigation algorithm, probably putting another check into step 1 of https://html.spec.whatwg.org/#process-a-navigate-response (alongside CSP's frame check and the as-yet-undefined X-Frame-Options).

Shared/ServiceWorkers

I think you're correct regarding the process model for shared and service workers.

I worry a bit about a service worker that does not assert COEP fetching resources that do not assert CORP, and laundering them into a document that does require CORP. In the current algorithm, the CORP check is called in "HTTP-network-or-cache fetch", which I think is skipped when responses come from a service worker.

Would moving that check to somewhere more like step 11 of https://fetch.spec.whatwg.org/#main-fetch be reasonable? I think that would address this concern by applying the checks to all responses, regardless of origin.

Loading

@annevk
Copy link
Member Author

@annevk annevk commented Jun 20, 2019

  • I suspect we might have to reject if the header value contains non-ASCII? After you do the decode you could do "is value an ASCII string" and treat it equivalently to a parse failure I suppose. It would be kind of nice if the caller did not have to do that though if all algorithms essentially require it. (File an issue at https://github.com/httpwg/http-extensions/issues/new?)
  • It does seem like creator referrer policy is unneeded, at least per HTML and the Referrer Policy standards: filed #4721.
  • If you do not specify unsafe-allow-outgoing, then non-matching popups will end up in their own browsing context group (and become a new top-level browsing that is not an auxiliary browsing context). If you do specify it they are allowed to not match and become auxiliary browsing contexts in the current browsing context group. https://gist.github.com/annevk/6f2dd8c79c77123f39797f6bdac43f3e has details. (Perhaps I should move that to a repository as well, as we are tweaking the model a bit. Or perhaps we should define it together with COEP given the overlap in a couple of cases.)
  • Yes, we'd have to move the CORP check to reject opaque responses without the header from a service worker. I don't think step 11 is appropriate because then redirects are not checked. We'll also need to change the "CORS flag" thing to instead check it being an opaque response.

Loading

@mikewest
Copy link
Member

@mikewest mikewest commented Jun 21, 2019

I suspect we might have to reject if the header value contains non-ASCII?

Added an issue to the document, and poked at httpwg/http-extensions#662 for clarification.

If you do specify it they are allowed to not match and become auxiliary browsing contexts in the current browsing context group.

Hrm. Does that match your understanding, @arturjanc? I find it a little surprising, but I'm also a bit out of the loop on COOP. :(

Or perhaps we should define it together with COEP given the overlap in a couple of cases.

I think defining COOP on its own is valuable, as it seems self-contained as a primitive that can be implemented and understood on its own, and complicated enough to benefit from a little bit of additional explanation around its purpose and approach.

That said, I think it would be very valuable to have a single, developer-facing document somewhere that outlined what impacts COOP and COEP have on the process model and on the availability of various APIs.

I don't think step 11 is appropriate because then redirects are not checked.

Would a new step inbetween 4 and 5 of https://fetch.spec.whatwg.org/#http-fetch be more appropriate? If not, do you have a different suggestion? :)

Loading

@arturjanc
Copy link

@arturjanc arturjanc commented Jun 21, 2019

"We might not need to inhert the COEP state into auxiliary frames" I think we have to if we want to allow SAB in combination with unsafe-allow-outgoing.

Hrm. Does that match your understanding, @arturjanc? I find it a little surprising, but I'm also a bit out of the loop on COOP. :(

I assumed that we would not allow SAB unless a page has COOP without unsafe-allow-outgoing; otherwise, an attacker could open non-cooperating documents in the same browsing context group and leak their contents. Ideally, SAB would only be available if you have COEP + COOP: same-origin.

The other values modes of COOP (same-site and unsafe-allow-outgoing) are still useful for sites that want to protect themselves from cross-origin attackers, but the restrictive mode that gives you SAB should probably require a stricter COOP.

Loading

@annevk
Copy link
Member Author

@annevk annevk commented Jun 23, 2019

How could it open non-cooperating documents if COEP is set as well?

Loading

@annevk annevk changed the title Opting into a CORS-only mode (Cross-Origin) Making postMessage() work for SharedArrayBuffer (Cross-Origin-Embedder-Policy) Jun 23, 2019
@arturjanc
Copy link

@arturjanc arturjanc commented Jun 23, 2019

It doesn't seem necessary for COEP to inherit into auxiliary documents, see Issue 4 in §3.1.1 in Mike's doc. If we required it then documents with SAB couldn't open popups to non-cooperating cross-origin documents, even though this would be safe because COOP would put them in a new browsing context group (it also seems inconsistent because presumably we'd allow regular navigations from the main COOP+COEP document to another document without the headers, relying on COOP to force a process swap).

IMHO it's also cleaner for COEP to only affect resource loads within the document and its iframes (primarily for the sake of browsers without OOPIFs) and leave it to COOP to put top-level documents in different browsing context groups; this should still give us the security properties we're looking for.

Loading

@annevk
Copy link
Member Author

@annevk annevk commented Jun 25, 2019

I think I'm okay with the model where COOP is effectively in charge as to whether or not a new browsing context group is to be created, while having to check COEP occassionally when doing so in order to make the right decision. This would indeed not work if unsafe-allow-outgoing would not disable SharedArrayBuffer as then COEP would also have to be in charge (as we'd have top-level documents without COOP enforcement).

Loading

@mikewest
Copy link
Member

@mikewest mikewest commented Jun 25, 2019

Ok. I'll update the COEP doc, and take a stab at a COOP doc. @arturjanc said he was willing to write a developer-facing threat model / process model doc. Maybe these will all end up being the same doc? Who knows.

I think we're pretty close to turning these into PRs and tests. :)

Loading

@rniwa
Copy link
Collaborator

@rniwa rniwa commented Jun 25, 2019

This has been a very long discussion and it's getting hard to follow what the latest proposal & consensus are. Can someone post a summary of the current COEP / COOP proposal?

Loading

@arturjanc
Copy link

@arturjanc arturjanc commented Jun 25, 2019

I started putting together a developer-facing COEP + COOP => SAB explainer of sorts, and should have something by tomorrow (it won't be perfect but it will hopefully be a starting point for something usable).

Loading

@annevk
Copy link
Member Author

@annevk annevk commented Jul 2, 2019

I have updated https://gist.github.com/annevk/6f2dd8c79c77123f39797f6bdac43f3e (Cross-Origin-Opener-Policy description) to account for unsafe-inherit (see #4581) and Cross-Origin-Embedder-Policy. In particular, how and when Cross-Origin-Embedder-Policy influences the "match". I hope this can help Mike's document and it might help Ryosuke though I think Artur will also post his high-level document soon.

Loading

@arturjanc
Copy link

@arturjanc arturjanc commented Jul 3, 2019

Apologies for the delay... Thanks to @mikewest's COEP spec and with a lot of help from @csreis and @annevk I jotted down a summary of the current proposal for COOP+COEP, along with some developer guidance for deploying the headers in this doc. This is by no means final, but should hopefully capture the main points from the various assorted discussions we've had -- please take a look and comment in the doc.

Loading

@Malvoz
Copy link
Contributor

@Malvoz Malvoz commented Jul 3, 2019

In the document:

Cross-origin resources can opt in via CORP (with a Cross-Origin-Resource-Policy header with a value which includes the requester, e.g., same-site, or cross-site for public resources)

But for CORP only same-site and same-origin is defined. So rather than cross-site it'd be the absence of a CORP header?

Loading

@annevk
Copy link
Member Author

@annevk annevk commented Jul 3, 2019

No, that's a new value. Absence of the header when COEP is in effect would result in a network error.

Loading

@arturjanc
Copy link

@arturjanc arturjanc commented Jul 3, 2019

A small caveat to the above is that the CORP requirement would apply only to non-same-origin resources. Loading same-origin resources would be allowed when COEP is in effect under (3) in §3.2.1 (same-origin iframes would still need to set COEP, though.)

CORP cross-site is defined in https://mikewest.github.io/corpp/#integration-fetch

Loading

@annevk
Copy link
Member Author

@annevk annevk commented Jul 8, 2019

While thinking about tests (if you want to help, please see web-platform-tests/wpt#17606 for material to review and contribute to):

  1. I think we should make workers specify COEP directly rather than inherit it and have enforcement be more similar to frames.
  2. I wonder if we should allow style sheets to specify a policy as well, similar to https://w3c.github.io/webappsec-referrer-policy/#integration-with-css. The main advantage would be that if you share your style sheets with others, they have a consistent fetching policy throughout. (This does not really work for scripts (except perhaps for imports).)

Loading

@clelland
Copy link
Contributor

@clelland clelland commented Jul 29, 2019

Somewhere along the way here I lost track of where credentialless subresources fit in the model -- has that been dropped entirely, or is there some way to achieve it with COEP/CORP?

I'd love to be able to use this to declare that certain subresources are public, having been fetched over the public internet (per CORS-1918), without any cookies/credentials attached.

I don't see it in the current proposal, but I could imagine something like Cross-Origin-Embedder-Policy: no-credentials being used to force that mode.

Loading

@annevk
Copy link
Member Author

@annevk annevk commented Aug 9, 2019

That's not part of the MVP and given the complexity of the "public internet" bit I don't think it should be. I'd support experimenting with it and iterating on it in parallel though. Would you mind opening a new issue?

Loading

@annevk
Copy link
Member Author

@annevk annevk commented Jul 8, 2020

This was fixed by a mixture of 70b8bb4 and c9d8983.

Loading

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
10 participants