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>

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.

For security:

  • I will be using an <iframe sandbox="allow-scripts">. This will block all popups, modals, form submissions, etc.
  • I'll be programmatically adding a meta tags 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?

  • Seems like an x/y problem, you're asking if some specific idea is secure, but instead you should be asking how can I do x securely. There are many examples of people hosting user controlled data(html) in a secure manner, but without knowing what you're trying to do its hard to give sensible advice.
    – wireghoul
    Jun 6 '21 at 23:01
  • Edited my question to make it more clear. Also, most sites which host user-controlled data (html) do it on a different domain (I guess to support legacy browsers and because sandboxing and csp might not have been widely supported when they started hosting the content). But I don't want a separate domain.
    – pepper
    Jun 7 '21 at 4:21

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.

  • Thanks for the answer! There is no inter-window messaging. I have edited my question a bit, I would be grateful if you can give any more insights.
    – pepper
    Jun 7 '21 at 4:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.