Open carvinlo opened 4 years ago
Unfortunately, it is impossible to create a real sandbox without using <iframe>
. Even if you use a proxy (which will cripple the perf + is not supported on older browsers) you'll can easily break out by event delegation or other techniques that eventually give you access to the full spectrum.
Right now this is one of the browser API limitations.
We usually recommend using zoid if stronger guarantees are needed.
I'll leave it open - maybe someone has other good insights or ideas.
I think we can also introduce an optional iframe
for stronger isolation here.
We'll need to do a spike regarding this, but from the top of my head the situation would be as follows:
For this to work the created iframe will have the app shell, too, but running in a special mode that does not load / display the full design, but only bringing the shared dependencies + layout to the pilet.
The advantage of this kind of architecture is that the pilet really does not care if it runs in an iframe or in the full app shell / main frame. It just works. All the proxying / magic is done by Piral.
Some maybe useful links for getting the components from the iframes embedded seamlessly:
That would, however, require one iframe per component, instead of one iframe per pilet (which may host multiple components).
Are there ways around it?
We'll need to do more thinking here.
- Host a single iframe, which is hidden and computes all its styles to inline them etc., then essentially moves the components renderings to the parent frame. This is like server-side rendering, just in the browser. PRO: Clean. CON: Not very efficient.
Can this solve:
If the pilet is running in an iframe, do we still need to deal with real-time synchronization of the environment (such as real-time synchronization of cookies) ? Or need to resolve the browser’s security restrictions on iframes? (such as https://www.netsparker.com/blog/web-security/same-site-cookie-attribute-prevent-cross-site-request-forgery)
What do you mean with "synchronization of cookies"?
The iframes would be created using srcdoc
, however, the pilet's script inside the iframe would still come from whereever the script source is. So in some sense it would be identical to the current solution, however, it would be isolated in the sense that the script cannot manipulate the app shell. All interaction would go via the messaging mechanism involving a Pilet API proxy. No other things can be proxied (e.g., manipulation of window
).
What do you mean with "synchronization of cookies"?
All requests inside pilet require to carry the token (stored in cookie) after login. If this problem should not exist in non-cross-domain scenarios, please ignore.
The iframes would be created using
srcdoc
Will not produce cross-domain, great.
@FlorianRappl Is the iframe suggestion is something you're still pursuing?
Yes definitely. It's planned for next year.
This is a framework for sandbox isolation through iframe: alibabacloud-alfa The article: Sandbox implementation of Alibaba Cloud open platform micro front-end solution
Thanks for the link @carvinlo - unfortunately, besides just having an iframe it does not solve any of the technical challenges we would face. We potentially render multiple things and need to dynamically place these at the right locations. We also need to dispatch functions (or their results) through a stringified asynchronous pipe.
Again, our idea here would be to discard the internal implementation details for the pilet developer. Only the app shell developers would determine which pilet (if any) will / should be sandboxed.
You can consider creating iframe just to do eval of module and dependencies and then return object from iframe to top. This would solve side-effects and versions incompatibility of dependencies and separatelly full isolation in standard iframe
Hi @alexogar you cannot do that. Only simple (JSON) objects can be transferred, and a function cannot be transported.
Let's pretend for a second that they could... you would have a completely different context in the other frame, so you cannot just render something from there. Rendering from the iframe has to be made inside the iframe. And then we are back to the layouting / synchronization issues described earlier here.
So the story is not as simple as you might think it is.
Basically you use iframe only to load JS so it does not interfere with side effects on others (e.g. webpack3 and webpack4 components) multiple versions of ag-grid and other examples. After it is evaluated in iframe you call function from top/parent window to register ready object (plugin/piral) and be rendered in main window.
We use that technique in our internal microfrontend framework. Idea is - you create an iframe with content of js you loaded + you add a function there which can be called by loaded js (e.g. register()) which will call window.parent function to register itself passing your component/piral there. Then it could be rendered using parent react-dom in parent window for example. I'm new to Piral project (found this project yesterday, and very exited ) and will`ll try to look around and craft small PR illustrating that, if I fail to do it here will do sample repo with that technique
Yeah that would be superb - thanks @alexogar ! Let me know how it goes - would be very cool to drive that forward! :beers:
New Feature Proposal
For more information, see the
CONTRIBUTING
guide.Description
I read your article before, thinking about sandbox isolation. I want to know what you think about the completely isolated sandbox solution, and whether there are other side effects. Such as Qiankun. What are your thoughts on sandbox and whether they will achieve similar functions in the future, thank you.
Background
[Provide any additional background for the feature, e.g., why is the current solution insufficient, what problem will it solve, etc.]
Discussion
[Optionally, outline any pros and cons you can currently think of to provide the basis for a solid discussion]