Last active
September 8, 2022 07:50
-
-
Save kumavis/8202447 to your computer and use it in GitHub Desktop.
dynamically creating a secure iframe
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
[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