Skip to content

Commit 0b76758

Browse files
committed
Enable iframe security through the 'sandbox' attribute
1 parent 4ec994e commit 0b76758

File tree

2 files changed

+34
-10
lines changed

2 files changed

+34
-10
lines changed

index.js

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ IFrame.prototype.parseHTMLOptions = function(opts) {
1717
if (!opts.head) opts.head = ""
1818
opts.html = '<!DOCTYPE html><html><head>' + opts.head + '</head><body>' + opts.body + '</body></html>'
1919
}
20+
if (!opts.sandboxAttributes) opts.sandboxAttributes = ['allow-scripts']
2021
return opts
2122
}
2223

@@ -28,14 +29,24 @@ IFrame.prototype.setHTML = function(opts) {
2829
opts = this.parseHTMLOptions(opts)
2930
if (!opts.html) return
3031
this.remove()
31-
this.iframe = document.createElement('iframe')
32-
this.iframe.setAttribute('scrolling', this.opts.scrollingDisabled ? 'no' : 'yes')
33-
this.iframe.style.width = '100%'
34-
this.iframe.style.height = '100%'
35-
this.iframe.style.border = '0'
36-
this.container.appendChild(this.iframe)
37-
var content = this.iframe.contentDocument || this.iframe.contentWindow.document
38-
content.open()
39-
content.write(opts.html)
40-
content.close()
32+
// create temporary iframe for generating HTML string
33+
// element is inserted into the DOM as a string so that the security policies do not interfere
34+
// see: https://gist.github.com/kumavis/8202447
35+
var tempIframe = document.createElement('iframe')
36+
tempIframe.setAttribute('scrolling', this.opts.scrollingDisabled ? 'no' : 'yes')
37+
tempIframe.style.width = '100%'
38+
tempIframe.style.height = '100%'
39+
tempIframe.style.border = '0'
40+
tempIframe.sandbox = opts.sandboxAttributes.join(' ')
41+
// create a blob for opts.html and set as iframe `src` attribute
42+
var blob = new Blob([opts.html], {type: 'text/html;charset=UTF-8'})
43+
var targetUrl = URL.createObjectURL(blob)
44+
tempIframe.src = targetUrl
45+
// generate HTML string
46+
var htmlSrc = tempIframe.outerHTML
47+
// insert HTML into container
48+
this.container.insertAdjacentHTML('beforeend',htmlSrc)
49+
// retrieve created iframe from DOM
50+
var neighborIframes = this.container.querySelectorAll('iframe')
51+
this.iframe = neighborIframes[neighborIframes.length-1]
4152
}

readme.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,25 @@ you can pass this into the constructor or `setHTML`
3030
head: string contents for `<head>`
3131
html: string contents for entire iframe
3232
container: (constructor only) dom element to append iframe to, default = document.body
33+
sandboxAttributes: array of capability flag strings, default = ['allow-scripts']
3334
scrollingDisabled: (constructor only) boolean for the iframe scrolling attr
3435
}
3536
```
3637

3738
you can also just pass in a string and it will be used as `{html: 'yourstring'}`
3839

40+
### security
41+
42+
by default the sandbox attribute is set with 'allow-scripts' enabled. pass in an array of capability flag strings. [Available flags](http://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/):
43+
```
44+
allow-forms allows form submission.
45+
allow-popups allows (shock!) popups.
46+
allow-pointer-lock allows (surprise!) pointer lock.
47+
allow-same-origin allows the document to maintain its origin; pages loaded from https://example.com/ will retain access to that origin’s data.
48+
allow-scripts allows JavaScript execution, and also allows features to trigger automatically (as they’d be trivial to implement via JavaScript).
49+
allow-top-navigation allows the document to break out of the frame by navigating the top-level window.
50+
```
51+
3952
## gotchas
4053

4154
iframes are weird. here are some things I use to fix weirdness:

0 commit comments

Comments
 (0)