WICG / anonymous-iframe

Give developers the ability to embed third party HTML documents inside a new and ephemeral context. In return, COEP embedding rules can be relaxed. Thanks to anonymous iframe, developers using COEP can now embed third party content that do not.
Other
25 stars 9 forks source link

Clarify/enable postMessage behaviour with SharedArrayBuffer #19

Open Zubnix opened 9 months ago

Zubnix commented 9 months ago

I could not find any information about this online hence this post.

Is there any way one can postMessage a SharedArrayBuffer from a cross-origin iframe to it's parent window? Every combination of headers or even setting the credentialless attribute on the iframe does not work it seems.

The real-life use case here is a WASM application/plugin inside a cross-origin iframe, who's memory needs to be read by the parent window. The memory can not be copied because of performance reasons (>100mb of data up to 100 times per second).

I would've expected the credentialless attribute on the iframe to allow this as it ensures no sensitive data is inside the iframe, but instead the current behaviour is a postmessage error event when trying to send the shared array buffer from the iframe to the parent.

putting the cross-origin iframe behind a reverse proxy so it has the same-origin is also not an option, because then the (untrusted) iframe has access to all parent state. While the parent just needs to have access to the iframe shared array buffer.

ArthurSonzogni commented 9 months ago

Hi @Zubnix,

TLDR: the iframe credentialless doesn't remove this constraint. You still can't share SharedArrayBuffer across different sites. [^1][^2]

[^1]: See also origin vs site

[^2]: I think you "might" be able for some time to share them across same-site-cross-origin documents, using document.domain setter, but all of this is becoming deprecated.


The iframe credentialless feature helps developers to embed additional kind of documents in a cross-origin isolated page. A cross-origin isolated page is required to transfert SharedArrayBuffer. However, the iframe credentialless doesn't modify algorithm to transfer SharedArrayBuffer at all. In particular, a SharedArrayBuffer can never leave its agent-clusters. See Chrome implementation.

Agent-cluster are a group of agent who can share memory. Currently, they only contains same-site documents:

  1. To share memory, two agents must share the same process. The best they can do is executing on differents threads on the same process (e.g. WebWorkers)

  2. For security, to avoid one site to corrupt the process and access data from another one, we execute different site into different processes, as much as possible. See site-isolation

So from (1) and (2), we can deduce the agent-cluster must only contain only same-site contexts.

There are project like the origin-agent-cluster to further limit this to same-origin.


@Zubnix, Does it helps?

+CC @camillelamy FYI.

Zubnix commented 9 months ago

@ArthurSonzogni

That certainly explains why it doesn't work but sadly doesn't help to make the use case work 😢

Do you happen to know if something like coop with restrict-properties would make it work?

If not, then it would be quite perverse that the only way to make it work is to give something untrusted (cross-origin) the status of fully trusted (same-origin) because the alternative is a broken application. It's like giving the postman the keys to your house because untrusted people are not allowed to put letters in your mailbox.

ArthurSonzogni commented 9 months ago

@Zubnix

Do you happen to know if something like coop with restrict-properties would make it work?

Indeed, it won't.

It doesn't help to make the use case work 😢

Web browsers worked extremely hard to isolate different site into different processes. In Chrome it tooks several years. This way, your "bank.com" doesn't share memory with "malicious.com". The whole idea is to use the OSes primitives to avoid two entities to share the same memory space. What you want is the opposite. It is unlikely to happen.

One might be able to share memory in between two processes using memory-mapped file on some OSes, but I guess this might be difficult, with its own set of problems.

What is your use case? Why does two website would like to share a SharedArrayBuffer?

Zubnix commented 9 months ago

@ArthurSonzogni The use case are desktop applications compiled to WASM that are rendered using a web compositor. These apps render to WASM [shared] memory, using existing native desktop libraries and protocol. Normally, on a native OS apps are visualised by running them in a separate process and communicating pixel data using a specific piece of shared memory between processes to avoid copying (performance), hence the need for something similar in the browser.

I can not use a normal arraybuffer because that is neutered once send (making the WASM code crash) and I can not create a subset of a sharedarraybuffer to further restrict the data that is share with another website/process (analogue to how you would do it between native processes) because that API simply does not exist for the web.

The whole idea is to use the OSes primitives to avoid two entities to share the same memory space. What you want is the opposite. It is unlikely to happen.

On the contrary, having processes with completely separate memory would be 💯 but what is needed is a way to do zero-copy transfer between 2 completely isolated sites/processes while still having a working [WASM] program, because now the solution is all (apps can see and do everything with each other) or nothing.

camillelamy commented 9 months ago

Unfortunately, the implementation of SharedArrayBuffers in Chrome does not support passing it from one process to another. This is why they cannot be passed cross-origin, as those origins might be hosted in a different process. If this is a functionality that would be helpful to you, I would encourage you to comment on the SharedArrayBuffer spec instead.