19

I'm trying to create an extensible platform, where my site will provide a model and some views (both client-side, in the browser) and third party sites may add their own views as well. The goal here is that only my model will make HTTP requests to my server, and the third party views shall only make API calls to my platform, nothing more (they may also "call home" if they want to, but they must not touch anything not explicitly exposed to them through the API).

The proposed solution is creating an invisible iframe for each third party extension, using only postMessage to communicate with them (Edit: to be a proper "view" it must be visible, of course, but as an alternative it can merely have the role of "controller", delegating the render of visual components to the main page - could be used if it added any security benefits, but ideally no). Would this properly "sandbox" the code? I'm assuming that:

  • They won't be able to access the DOM of the main page, or make arbitrary JavaScript calls on it, or make Ajax request on my domain, due to same-origin policy;
  • They might make GET requests on my server (including loading scripts from it), but as long as I use CSRF tokens where it matters I should be fine. This situation is no different from having two open tabs in the same browser, one of them authenticated with its respective site;
  • They won't be able to clickjack the user, since if their iframes are invisible; I'm also assuming they can't make them visible or resize them, since this would involve accessing the DOM of the parent page, is this correct?
  • They can spam Window.alert (or worse: Window.prompt), console.log or access other "global" stuff. This is the worse problem I identified so far, and still unable to think of ways to prevent that.
    • Clarifying: the issue here is the possibility of trying to impersonate the parent site, displaying a message asking for the password, for instance.
    • Also, correct me if I'm mistaken - I'm assuming JavaScript in iframes has equal access to those resources, and no way for parent page to deny that.
  • They can embed flash or other plugins which may have security vulnerabilities. The fact it's in an iframe, however, does not make it worse in any regard, or am I mistaken?

Are these assumptions correct, is there anything else I should be aware of? Some level of trust will be necessary from the part of users (the idea is that each user should be able to choose extensions at his own leisure, regardless of my site endorsing them or not, while ultimately bearing the consequences of his choices), but I'd like to do everything possible to mitigate those risks.


Update: I'd like to clarify the question a bit, based on the questions raised by commenters. There are many reasons to include third-party scripts in a page - advertisement, analytics, interaction with social networks, etc. This is a security concern though, in fact it's one of the reasons people use AdBlock or NoScript (so you can seletively choose which domains are allowed to run code in your browser). Usually the site trusts the third parties whose scripts it includes, but not always (Facebook applications, for instance, can be made by anyone - but they run inside a Facebook page), and I have seen iframes been used to "isolate" third-party contents.

Though one option for cross-site communication in the browser is having two open tabs (or windows) using postMessage to exchange messages, a single page provides a more seamless experience. The full implications of using iframes (visible or invisible), and its viability in sandboxing untrusted contents, is my main concern in this question, and IMHO is applicable for a wider audience too (see paragraph above).

In my particular case, I'm trying to avoid having the embedded contents impersonate the parent site (see clarification in the 4th bullet point above) and to protect users in general from other nuisances as far as I can. While each user will have the capability to choose his own extensions, being ultimately responsible for the consequences, I'd like to mitigate any known problems that are within my reach (and try to educate users for those that aren't).

mgibsonbr
  • 2,925
  • 2
  • 21
  • 35
  • 1
    I'm having trouble understanding the problem. It sounds like it's all client-side code (javascript)? What are the third party "views" for if they are in invisible iframes? Is it to enrich data presented elsewhere on the page? Then why not do this on the server side where you'll have much more control? – Louis Somers May 19 '12 at 09:50
  • I agree with @LouisSomers, I don't get what you want to do exactly. In what will be made the view? Do you mean the third party will be able to have their own view (HTML/JS/CSS) in your website? – Cyril N. May 19 '12 at 14:30
  • The goal is a bit similar to what Google Wave did: provide a "generic" data model, persistence, communication, etc, while allowing third parties to build new things upon it. In principle the iframes were not meant to be invisible (so yes, they would provide HTML/JS/CSS) but I'm more inclined toward restricting extensions to the role of "controller" (which will render the view solely through my API). The problem I'm trying to solve is determine the viability of all this, and it boils down to the question: are there unforeseen consequences of having untrusted third party code running in iframes? – mgibsonbr May 19 '12 at 18:35

2 Answers2

12

You said you are going to load the third-party content in an iframe, but will the third-party content be hosted from the same domain as your main content, or will it be served from a separate domain?

If the third-party content is hosted on the same domain as your main page, then no, your approach is totally insecure. Content in an iframe has full scripting access to the main page, if it is served from the same origin (roughly, the same domain). Read about the same-origin policy.

A more reasonable approach is to host the third-party extension content on a different domain than your main page. If you do this, then yes, your approach gives reasonable security. The extension content will be sandboxed and will be unable to mess with the main page (for the most part). There are some remaining risks, noted below:

  • The third-party content in the iframe can navigate the main page (e.g., by setting window.location or top.location). Thus, the third-party content replace the entire page with content of the third party's choosing. This might allow for phishing or spoofing attacks. An alert user might notice such attacks, because the URL in the browser's address bar will change, but some users might not notice.

  • The third-party extension can still load unsavory content in its own iframe (e.g., porn, ads, etc.).

  • The third-party extension can still try to mount drive-by download attacks on your users. If your users have a vulnerable browser, they might get infected by the attack (of course, this may be true if they visit any malicious site; there is nothing about iframes that increases the risk -- it just doesn't make it go away, either).

  • The third-party content can play movies or sound, possibly annoying users.

  • The third-party extension may be able to mount click-jacking attacks on the main page. (You mention that the iframe will be invisible, but I'm not sure exactly what are the specific methods needed to ensure that this is a robust defense against click-jacking. There are a lot of browser quirks out there.)

  • It is important that your site use strong CSRF defenses. Otherwise, the third-party content will be in a perfect position to mount CSRF attacks.

Many of these risks are relatively minor and may be acceptable in most cases, but I wanted to outline them for you and for others.

An alternate approach is to use a system for Javascript sandboxing (these can also be thought of as a way to build a "virtual iframe"). See, e.g., Caja, SES, ADsafe, FBJS, and Microsoft's Web Sandbox.

You could also look at sandboxed iframes, but I don't think they're supported on all browsers, so you can't rely upon this mechanism for security yet (sadly).

See also What risks should I be aware of before allowing advertisements being placed on my website?, Security issues using iframes, How to scan Javascript for malicious code?.

Also, for details about browser quirks relating to the same-origin policy and that sort of topic, I highly recommend the Browser Security Handbook.

D.W.
  • 98,860
  • 33
  • 271
  • 588
  • Thanks for the feedback, especially for the links regarding JS sandboxing, I'll take a closer look at those. Your first bullet point is indeed what worries me most (see also [this example](http://lcamtuf.coredump.cx/switch/) of a possible exploit), and unfortunatly there's little I can do about it (postMessage will give the third-party page - regardless of being in an iframe or not - a reference to my `window`, so I believe they could still perform such attack). Overall I think the outlined risks are acceptable in my particular case, but if I can use one of those sandboxing tools, even better. – mgibsonbr May 21 '12 at 07:07
  • 1
    Just created a [small example](http://difnet.com.br/codesamples/sandboxpostmessage/try_sandbox.html) that refutes my assumption in the comment above: in browsers that support sandboxed iframes, getting a reference to the `window` object (using `event.source`) does **not** enable it to change the browser location. That makes the iframe even **safer** than a separate window/tab, since the latter is not sandboxed, and becomes able to navigate my page away as soon as it receives a message from it. – mgibsonbr May 22 '12 at 02:44
2

If you visit this demo you'll see that the code detects itself in a frame (can be modified to detect what page its on) than changes the url. A url which may impersonate the parent site. (sidenote i notice google and yahoo came up blank and i believe its bc their headers send "X-Frame-Options:SAMEORIGIN")

I dont know much about controlling windows so it may be possible for another window to close your site and launch another window to impersonate it. But from a DOM and javascript standpoint it should be safe for their code to execute w/o causing your users harm. However tricking the users is another story.

  • Thanks for the demo, it indeed confirms the iframe can mess with the parent site `location`. I know it's possible to have a good level of control over windows you opened yourself (using `window.open` for instance), and there are many [nasty](http://lcamtuf.coredump.cx/clickit/) [things](http://lcamtuf.coredump.cx/switch/) an attacker can do with it, but I'm unsure whether or not any tab can control any other tab (I've seen many claims that the answer is **no**, and so far I found no evidence in contrary). – mgibsonbr May 21 '12 at 06:38
  • 1
    @mgibsonbr: wow that is pretty evil. One thing that has been bothering me is if in the case you cant see the iframe why have it at all? Browsers really need to support sandboxing. Actually chrome seems to handle my demo ok as long as allow-top-navigation isn't used (in the sandbox attribute) http://www.w3schools.com/html5/att_iframe_sandbox.asp –  May 21 '12 at 07:33
  • you're right, if they are invisible there's no need for them [to be iframes], a simple way to sandbox some code would suffice. I just added a small clarification in the question, but the main point is allowing (simplifying) the creation of new tools that will act on/make use of my model, even if they produce no (direct) visual effect. BTW thx for mentioning the html5 iframe sandbox, didn't know about it, and I can already see it opens some new, interesting possibilities (as long as it becomes widely supported, that is, which I hope is soon). – mgibsonbr May 21 '12 at 08:53
  • The link to the demo no longer works. – Thunderforge Oct 13 '15 at 20:00