Using iframes for a sandbox?

I am developing a system that allows custom javascript in widgets. To keep everything safe, I plan to isolate these widgets in an iframe. Of course, in order for the sandbox to be effective, the iframe must have a different domain than the parent.

I would really like to dynamically generate an iframe with code like this:

template = '<html><body><script>/* user code */</script></body></html>' src = 'javascript: document.write("' + template + '")' widget = $('<iframe>').attr('src', src) $('#container').append(widget) 

... and then get the resulting iframe as a cross-domain from the parent window. Is this possible, and if so, how to do it?

+1
source share
1 answer

Ok, I think I get what you need, but it's a little complicated. Do you want to create an <iframe> and populate it with client-side Javascript client, but still have an isolated client?

This is pretty non-standard. Typically, <iframe> content is created on the server side. But here it happens.

First, some documents: documents cannot access the contents of any document that does not belong to one domain (including a subdomain) and port. But they can change their own security domain using the document.domain property. So what you need to do is ease the security, and then tighten it again for the user script to run.

Thus, you cannot do it the way you specified, because if you create an <iframe> with Javascript src , then document.domain will match the parent frame. This means that the widget will have full access to everything.

So how can you do this:

  • Set up two subdomains of your primary domain. Call them home.example.com and widgets.example.com .
  • Create a basic HTML file at widgets.example.com and make sure it invokes this javascript: document.domain = "example.com";
  • Now create your page that will contain all these widgets. Set its document.domain to the same value.
  • Create all your frames by loading the main HTML page from widgets.example.com into it.
  • Set the variable inside the frame that contains the user template. Example: myFrame.contentWindow.foo = "template";
  • Switch document.domain to the main window back to home.example.com so that <iframe> no longer has access to the parent frame
  • Start template replacement in frame

This last part is the hard part. You can’t just embed the code, because if it starts automatically, it will be launched before you can change the domain of the home document back, which will be a security problem. So instead, you need to set it to a temporary variable inside the frame, and then run the frame to replace its own contents with this template, but only after everything is locked. The easiest and most compatible way is to call it when resizing, and then just change the width or height of the frame.

Now, as an alternative, if the widget has been populated on the server side:

  • Host widget at widgets.example.com
  • The host page containing the widget at home.example.com
  • Done

But I assume that you have reasons to do all this on the client side.

The following topics are logical: communication between frames and automatic sizing. But this is the next day.

Do I answer your question? I hope because it was a lot of typing, and I will not mind the reputation points if you vote and agree with my answer !;)

+3
source

Source: https://habr.com/ru/post/922614/


All Articles