Skip to content

Instantly share code, notes, and snippets.

@kumavis
Last active September 8, 2022 07:50
Show Gist options
  • Save kumavis/8202447 to your computer and use it in GitHub Desktop.
Save kumavis/8202447 to your computer and use it in GitHub Desktop.
dynamically creating a secure iframe
//
// Update: Resolved. TL;DR: chrome dev tools troll.
// Outputting iframe object to console resulted in enumeration of properties, throwing the SecurityError
// Note: However, accessing iframe.contentDocument does throw a SecurityError so iframe.contentDocument.write is not possible.
//
//
// Problem
//
// dynamically created iframe with sandbox attribute
// wont allow you to add it to the DOM
// create iframe
var iframe=document.createElement('iframe');
iframe.sandbox='allow-scripts';
// attempt to insert iframe into container, error!
document.body.appendChild(iframe);
//=> Sandbox access violation: Blocked a frame at "https://gist.github.com" from accessing a frame at "null". The frame being accessed is sandboxed and lacks the "allow-same-origin" flag.
// Note: this here is the above mentioned "chrome dev tools troll."
// setting the sandbox attribute late
// doesnt update the security policy
// create iframe
var iframe=document.createElement('iframe');
// insert iframe into container
document.body.appendChild(iframe);
// set security policy after
iframe.sandbox='allow-scripts';
// attempt to break security. it is broken.
iframe.contentWindow.eval('top')
//=> Window {top: Window, window: Window, location: Location, external: Object, chrome: Object…}
//
// Solution
//
// append html string to DOM that creates the iframe with the desired sandbox setting
// create html string
var iframe=document.createElement('iframe');
iframe.id='fancy-sandbox';
iframe.sandbox='allow-scripts';
var iframeSrcString = iframe.outerHTML
// insert iframe into container
document.body.insertAdjacentHTML('beforeend',iframeSrcString);
// get reference to created iframe
var sandbox=document.getElementById('fancy-sandbox');
// attempt to break security
sandbox.contentWindow.eval('top')
//=> SecurityError: Blocked a frame with origin "https://gist.github.com" from accessing a cross-origin frame.
@kumavis
Copy link
Author

kumavis commented Jan 1, 2014

[10:13am] hjdivad: on line 12 where are you getting this error?
[10:13am] hjdivad: in chrome dev tools?
[10:13am] kumavis: yes
[10:13am] hjdivad: okay, things are probably fine
[10:13am] hjdivad: i suspect the first case actually works
[10:14am] hjdivad: try document.body.appendChild(iframe); ""
[10:14am] kumavis: ah, interesting
[10:14am] kumavis: you're right on the money
[10:14am] hjdivad: here is what I think is happening: the chrome dev tools is a REPL. Note the 'P' is print. What dev tools is trying to do is print the result of document.body.appendChild(iframe) which is the iframe itself. In older versions of dev tools this involved traversing every property on the object
[10:14am] kumavis: no error thown
[10:15am] hjdivad: which will cause an error because only a few properties are allowed to be read from a different context
[10:15am] hjdivad: basically you can compare the identity of the window but that's it
[10:15am] hjdivad: newer versions of chrome don't do this
[10:15am] hjdivad: make sense?
[10:15am] kumavis: Version 31.0.1650.63
[10:15am] kumavis: yeah that makes sense
[10:15am] hjdivad: mmm, you might want to try in canary
[10:16am] hjdivad: but in any case, the error is chrome trying to print the result, and not from the append operation itself

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment