Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sandboxing content in an IFRAME, on the client side

The issue

I have some javascript content that I want to "sandbox" into an iframe:

<script type="text/javascript">
    doSomethingPotentiallyMalicious( // ideally, i want this to be able to run...
        top.document.getElementById('sensitive_information') // ...but want this to fail due to cross-domain permissions
    );
</script>

The catch is, due to the nature of our web application, I need to do this inline on the parent page that contains the iframe, and I need to do this in a cross-browser compatible way.

Data URL...almost but not quite

I was able to get the desired effect in Chrome by setting content in the iframe via a data url:

<iframe id="sandbox" src="data:text/html;charset=utf-8,%3Cscript%20type%3D%22text%2Fjavascript%22%3E%0A%20%20%20%20doSomethingPotentiallyMalicious(%20%2F%2F%20ideally%2C%20i%20want%20this%20to%20be%20able%20to%20run...%0A%20%20%20%20%20%20%20%20top.document.getElementById('sensitive_information')%20%2F%2F%20...but%20want%20this%20to%20fail%20due%20to%20cross-domain%20permissions%0A%20%20%20%20)%3B%0A%3C%2Fscript%3E"></iframe>

However, data url support is spotty and this needs to work cross-browser.

Document.write gets the content there, but lacks cross-domain security

I can have the unsafe content in a javascript escaped string, and then write it as the content of an iframe:

<iframe id="sandbox" src="http://google.com/"></iframe>
<script>
    var unsafeContent = '\x3Cscript\x20type\x3D\x22text\x2Fjavascript\x22\x3E\x0A\x20\x20\x20\x20doSomethingPotentiallyMalicious\x28\x20\x2F\x2F\x20ideally,\x20i\x20want\x20this\x20to\x20be\x20able\x20to\x20run...\x0A\x20\x20\x20\x20\x20\x20\x20\x20top.document.getElementById\x28\x27sensitive_information\x27\x29\x20\x2F\x2F\x20...but\x20want\x20this\x20to\x20fail\x20due\x20to\x20cross\x2Ddomain\x20permissions\x0A\x20\x20\x20\x20\x29\x3B\x0A\x3C\x2Fscript\x3E\x0A\x0A';
    var sandbox = document.getElementById('sandbox');
    sandbox = (sandbox.contentWindow) ? sandbox.contentWindow : (sandbox.contentDocument.document) ? sandbox.contentDocument.document : sandbox.contentDocument;
    sandbox.document.open();
    sandbox.document.write(unsafeContent);
    sandbox.document.close();
</script>

The problem with this is, once I write that content to the iframe, the cross-domain security is apparently no longer there (meaning that doSomethingPotentiallyMalicious function has access to the everything in the parent window).

Document.write + Document.domain doesn't seem to get us there, either

I even tried changing the document.domain (by removing the left-most domain so "www.example.com" becomes "example.com") per this previous SO post, but this doesn't seem to enforce a cross-domain policy, either:

<iframe id="sandbox" src="http://google.com/"></iframe>
<script>
    // prepended to unsafeContent: document.domain = document.domain.replace(/^[\w-]+\./,'');
    var unsafeContent = '\x3Cscript\x20type\x3D\x22text\x2Fjavascript\x22\x3E\x0A\x20\x20\x20\x20document.domain\x20\x3D\x20document.domain.replace\x28\x2F\x5E\x5B\x5Cw\x2D\x5D\x2B\x5C.\x2F,\x27\x27\x29\x3B\x0A\x20\x20\x20\x20doSomethingPotentiallyMalicious\x28\x20\x2F\x2F\x20ideally,\x20i\x20want\x20this\x20to\x20be\x20able\x20to\x20run...\x0A\x20\x20\x20\x20\x20\x20\x20\x20top.document.getElementById\x28\x27sensitive_information\x27\x29\x20\x2F\x2F\x20...but\x20want\x20this\x20to\x20fail\x20due\x20to\x20cross\x2Ddomain\x20permissions\x0A\x20\x20\x20\x20\x29\x3B\x0A\x3C\x2Fscript\x3E\x0A\x0A';
    var sandbox = document.getElementById('sandbox');
    sandbox = (sandbox.contentWindow) ? sandbox.contentWindow : (sandbox.contentDocument.document) ? sandbox.contentDocument.document : sandbox.contentDocument;
    sandbox.document.open();
    sandbox.document.write(unsafeContent);
    sandbox.document.close();
</script>

Is what I'm trying to do even technically feasible at this point?

like image 767
EvanK Avatar asked Aug 10 '12 21:08

EvanK


People also ask

What is Sandboxing the iframe?

The sandbox attribute enables an extra set of restrictions for the content in the iframe. When the sandbox attribute is present, and it will: treat the content as being from a unique origin. block form submission. block script execution.

Why would you use the sandbox attribute with an iframe?

Applying the sandbox attribute to iframes you include allows you to grant certain privileges to the content they display, only those privileges which are necessary for the content to function correctly.

Is iframe sandbox secure?

Now, these are things that have a great security risk, so to make things more secure for the users, W3C added the 'Sandbox' attribute in the HTML specifications. This attribute limits the action from an iframe within a web page and makes it quite secure and protected.

What is a sandboxed embed?

An embed enables you to include a sandbox in your documentation, blog post, or website using an iframe, or anywhere with Embedly support, like Medium, Reddit, Trello, and Notion. You can show just the code, the preview, or both at the same time. CodeSandbox has a separate application for the embed.


1 Answers

I wonder if window.postMessage would work. You could set up an iframe that evals the first message it receives to inject javascript into it. According to the site I linked, it works in Firefox, IE8+, Opera, Safari, and Chrome. Hopefully that's cross-browser enough for you. Mobile devices might have issues with it.

like image 77
Nathan Breit Avatar answered Sep 22 '22 20:09

Nathan Breit