Avega
Avega

Reputation: 186

User-defined iframe on page

Is it safely to allow user to define iframe content, which will be showed on page?

For example. There is form to submit some html markup text. This text will be showed at some page in iframe.

UPD: Another try to explain: There is a page with next content:

<html>
<head>...</head>
<body>
  ...
  <iframe>
     #document
     user-defined content here
  </iframe>
  ...
</body>
</html>

Where is "user-defined content" is user-defined content. Users can write some html-markup, wich will be showed at this page. If user-defined content will be something like this:

<head>...</head>
<body>
  <p>I am awesome user!</p>
</body>

Then page content will be next:

<html>
<head>...</head>
<body>
  ...
  <iframe>
     #document
     <head>...</head>
     <body>
        <p>I am awesome user!</p>
     </body>
  </iframe>
  ...
</body>
</html>

Upvotes: 1

Views: 173

Answers (3)

SilverlightFox
SilverlightFox

Reputation: 33538

Usually not safe as you would leave your site open to XSS.

However, you could implement a Content Security Policy for the page that outputs the Iframe.

This will effectively allow you to disable scripting on that page, so if a user enters any <script> tags or uses attributes that usually cause client-side script to run, they will be ignored by the browser.

This is implemented through a HTTP response header. e.g.

Content-Security-Policy: script-src 'self' https://apis.google.com

This above header would allow scripts from https://apis.google.com to execute, and scripts from the local domain to execute, but it would prevent inline scripts in the HTML. These options are configurable to do whatever you need.

Upvotes: 1

bobince
bobince

Reputation: 536349

<iframe>
    user-defined content here
</iframe>

Firstly, this doesn't actually work. The content of the <iframe> tag is only shown as fallback for ancient browsers that don't support iframes, you can't include body content there. To inject content into an iframe from the parent page you would have to either:

  • encode it into a data: URL (won't work in IE)
  • put it in an iframe srcdoc attribute (recent HTML5 edition, not well supported)
  • write the iframe document content from JavaScript in the parent page.

If you do one of these, or if you have user content served from another URL under the same hostname, then the content has the same JavaScript Origin as your site, and any attacker script in the iframe will have access to and control of everything in the user's session on your site. Wrapping same-origin content in an iframe alone doesn't give you any kind of security boundary.

Usually this would constitute a cross-site scripting (XSS) attack and would not be considered acceptable. It's conceivable you might have an unusual user model where XSS doesn't cause a problem, but if you've got anything like access authorisation based on logged-in user, or password-protected accounts, then XSS would break those kinds of measures.

If you want to allow arbitrary HTML content without breaking access control then you must either:

  • remove scripting ability by sanitising the input against a whitelist of known-good tags and attributes (this is not straightforward, so look for tried and tested libraries to do it for you, eg htmlpurifier if you're using PHP);

  • in the future, iframe sandbox could also remove scripting from the iframe content, but that's not reliably supported enough yet;

  • if you must allow script then, as Quentin suggested, serve the user content from a different domain.

(There are still things to worry about when including arbitrary HTML content in an iframe, like phishing and reverse-clickjacking attacks, but nothing as bad as XSS.)

Upvotes: 3

Quentin
Quentin

Reputation: 943217

There are basically three things that could go wrong with this:

  • A CSRF attack. Implement the usual defences against them.
  • The user submitting broken data. This isn't generally a problem.
  • The user being tricked into submitting harmful data through social engineering (a self-XSS attack).

Isolate the iframe so code in it can't touch your main site. Put the code that generates the content for the iframe on a different domain to the code that loads the frame.

Upvotes: 2

Related Questions