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

Enable SharedArrayBuffer for apps #605

Closed
jozefchutka opened this issue Jul 17, 2024 · 18 comments
Closed

Enable SharedArrayBuffer for apps #605

jozefchutka opened this issue Jul 17, 2024 · 18 comments
Labels
idea An idea for a feature/improvement

Comments

@jozefchutka
Copy link

As discussed on https://discord.com/channels/1071986474041495705/1224431787808129138/1263169223274791036 , I would like to request SharedArrayBuffer (cross origin isolation) for apps.

Here is a good article describing the importance and how to enable it https://web.dev/articles/cross-origin-isolation-guide

@jozefchutka jozefchutka added the idea An idea for a feature/improvement label Jul 17, 2024
@jelveh
Copy link
Contributor

jelveh commented Jul 17, 2024

Thanks again. Looking into this ✌️

@KernelDeimos
Copy link
Contributor

One of the instructions on that article says this:

This blocks communication between your top-level document and its popup windows

Puter relies heavily on postMessage - that's how apps communicate with Puter (and via Puter is how apps communicate with other apps). Unless there's a way for postMessage and this to coexist, we may not be able to support this. I feel like there should be some way around it though, maybe some way to communicate to the browser that the way we're doing iframe messaging is reasonably secure.

@jozefchutka
Copy link
Author

jozefchutka commented Jul 18, 2024

I made a quick POC, you can try running on your side:

https://domain-a/main.html served with

Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
<iframe src="https://domain-b/iframe.html" allow="cross-origin-isolated"></iframe>
<script>
console.log(`main has SharedArrayBuffer ${window.SharedArrayBuffer ? "TRUE" : "FALSE"}`)
const iframe = document.querySelector("iframe");
setInterval(() => iframe.contentWindow.postMessage("hello from main", "*"), 1000)
onmessage = event => console.log("main.onmessage", event.data);
</script>

https://domain-b/iframe.html served with:

Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Resource-Policy: cross-origin
<script>
console.log(`iframe has SharedArrayBuffer ${window.SharedArrayBuffer ? "TRUE" : "FALSE"}`)
setInterval(() => parent.postMessage("hello from iframe", "*"), 1000);
onmessage = event => console.log("iframe.onmessage", event.data);
</script>

now open https://domain-a/main.html in browser and console prints:

main has SharedArrayBuffer TRUE
iframe has SharedArrayBuffer TRUE
iframe.onmessage hello from main
main.onmessage hello from iframe

tested in chrome and firefox

@KernelDeimos
Copy link
Contributor

I've added a config option for self-hosted installations. This will allow us to do further testing within Puter and make sure everything still works. In the meantime you can test your app in this environment to ensure SharedArrayBuffer works now.

@jozefchutka
Copy link
Author

Thanks for looking into it. As I am not running self-hosted installation, I will wait until this lands on puter.com. Please keep this thread updated... I would like to add 2 mighty apps 💪 .

@KernelDeimos
Copy link
Contributor

If we add these headers on puter.com it breaks an important feature. However, it looks like we're able to add these headers to deployed apps (if you're hosting a static app on Puter, the contents of that iframe can have those headers in its response). Does that work, or does it need to be the root window in the tree?

@jozefchutka
Copy link
Author

To my knowledge, if the top window (puter.com) is not isolated (doesnt have SharedArrayBuffer) the iframes loaded within it will not be isolated (no SAB) either no matter what headers are sent with these iframes ( https://stackoverflow.com/questions/69322834/is-it-possible-to-embed-a-cross-origin-isolated-iframe-inside-a-normal-page ). I can confirm this following my own testing.

@KernelDeimos
Copy link
Contributor

We have some more ideas. Adding cross-origin isolation breaks a lot of Puter apps hosted on 3rd party sites. What I think we're going to have to do is allow the user to enter a mode where the headers are sent by puter.com ("isolated mode" or "high-performance mode" - something like that). I don't understand why we can't tell the browser "act as if these iframes are also isolated" for 3rd-party sites, but I don't yet understand this security mechanism very well.

@jozefchutka
Copy link
Author

Are you considering the whole puter.com being isolated, but by default the app iframes will be not? And so author of the app will have a chckbox to change this mode for a particular app/iframe?
I agree that the whole isolation model is quite confusing.

@KernelDeimos
Copy link
Contributor

Isolating puter.com seems to be what breaks the 3rd-party apps actually. What I'm suggesting is introducing state with the user's session, or a url/query parameter for puter.com, that would cause the server to send these headers for puter.com. This would require a page reload or for Puter to be opened in a new tab, so the solution isn't super great but it might be the best. I think we can make it a bit better if we embrace the "this app will open in puter but in a new tab" idea by improving Puter's understanding of other Puter tabs (i.e. showing the user what apps are open in different tabs).

@jozefchutka
Copy link
Author

I see, Thats not optimal. Having an app in a new tab/window feels like I could open the app url directly without puter being involved at all,

What is it that breaks within other 3rd party apps? If I know a little more I might be helpful to resolve

@KernelDeimos
Copy link
Contributor

KernelDeimos commented Jul 19, 2024

What is it that breaks within other 3rd party apps? If I know a little more I might be helpful to resolve

As I understand it, when we add these headers on puter.com:

Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin

any app from a third-party origin (example.com/puter-app) is not allowed to load within an iframe at all. (that's what we observed when testing it - I imagine if the server hosting the app sent those headers as well it would work)

@jozefchutka
Copy link
Author

once puter.com sends COOP: same-origin + COEP: require-corp or credentialless,

the example-app.com can be loaded in iframe when:

  1. example-app.com sends COEP:require-corp or credentialless + CORP: cross-origin (works in chrome, firefox)
  2. or embedded as <iframe credentialless src...> (works only in chrome)

On top of that for example-app.com to have access to SAB <iframe allow="cross-origin-isolated"> is needed for chrome

So until safari and firefox delivers the needed <iframe credentialless> the options are:

  1. all apps sends COEP+CORP
  2. puter encourages users to drop firefox/safari and use chromium based browsers

This has been problematic since the whole COOP/COEP was invented, esp common case is embedding youtube videos to isolated sites (SO)

Related POC:
https://iframe-credentialless.glitch.me/

@KernelDeimos
Copy link
Contributor

Thanks for looking into that! We can definitely add the attributes that make this work in chromium and hope that other browsers add support later. I don't know if we'd want to go so far as encouraging users to drop Blink competitors - I actually think we need more browser diversity (the Ladybird project for example is trying to accomplish this), but I think we can detect a chromium UA string and enable cross-origin-isolation for that case, showing a "this only works in chromium" message on apps requiring this feature.

@KernelDeimos
Copy link
Contributor

I think we got it! Give it a try, we've already deployed the changes to puter.com as well.

@jelveh
Copy link
Contributor

jelveh commented Jul 21, 2024

@jozefchutka our fix is live on puter.com. I tested SharedArrayBuffer inside an app (to the best of my ability lol) and it seems to be working now! 🔥

@jozefchutka
Copy link
Author

I can cofirm having SAB available in my app. Thank you for fast iteration and delivery. Great job. (feel free to close this issue, seems resolved to me)

@jelveh
Copy link
Contributor

jelveh commented Jul 21, 2024

Awesome to hear! 🎉

@jelveh jelveh closed this as completed Jul 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
idea An idea for a feature/improvement
Projects
None yet
Development

No branches or pull requests

3 participants