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.
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.
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).
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?
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With