srcdoc attribute of iframes as a source of XSS attacks
I am trying to implement a case where a user provides us some html code which is then stored in our database. We then retrieve the HTML from our database as a string. (We have no control over the user input)
I try to embed this html using
const htmldoc = [the raw html] <iframe sandbox="allow-scripts" srcdoc=htmldoc> </iframe>
I would be using a data:// URI. Or blob:// URI.
I am using the sandbox attribute to prevent Same Origin Policy. Can a user input something which might lead to XSS attacks in the parent browsing context? I am not concerned if the XSS attack targets the content inside the iframe since it is sandboxed.
If my approach is vulnerable to attacks, what can I do to make it secure?
Here is what I am planning to do:
I will have the user input which will be raw HTML data. I will store this file somewhere. Whenever I have to render this HTML, I'll make an API call to retrieve it.
- I will be using an
. This will block all popups, modals, form submissions, etc.
- I'll be programmatically adding a
metatags to the HTML which is to be rendered.
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src https://trusted-site.com/ 'unsafe-inline' style-src https://trusted-site.com/; font-src https://trusted-site.com/; img-src https://trusted-site.com/"> <meta name="referrer" content="no-referrer">
What are the possible attack vectors in this approach? Is there anyway I can make it more secure against the possible attack vectors?
- I will be using an
First of all, if you're using data: or blob: URIs, you should use the src attribute; srcdoc is for actual content to embed in the document (e.g. pull it out of your DB and escape all the quotation marks).
Overall, this should be reasonably safe. The sandboxed iframe being allowed to run scripts means it could attempt to create new windows or pop messages that overlay your page's content or display alert or input boxes to the user, though they should not quite appear to come from your page exactly due to the iframed page having a unique origin. If you enable any form of inter-window messaging (
addEventListener('message'...)) then the iframe could attempt to communicate with the parent, and potentially attack the event handler. Otherwise, though, you should mostly be safe.