views:

160

answers:

2

I'd like to enforce a requirement that client script inside a page (which in turn is loaded inside an iframe of another page) will only run when the parent page is on the same top-level domain as the framed page (although it may be on another hostname in that domain). Is this do-able?

I assume that the easy solution of looking at top.location.host won't be available due to cross-site scripting limitations, but I'm wondering if other javascript hackery could suffice.

Constraints on any potential solution inculde:

I need to be able to run XmlHttpRequest calls inside the child page, and I need to validate that the hostname is in the same domain before I make those calls. (this makes a document.domain solution challenging because AFAIK setting document.domain disables the ability to make XmlHttpRequest calls.

I can control client-side script and HTML on both parent or child (and I can create new pages if needed), but I can't make any server-side code changes.

I can't simulate the above via server-side calls or proxies, because the child page's hostname uses a forms auth system with hostname-scoped cookies that I can't get access to from the parent page since it's on a different hostname.

I don't have enough control over the child-frame site to be able to put both sites behind the same reverse-proxy or load-balancer (which would enable me to put both sites on the same hostname).

I don't actually need to access any UI inside the IFrame-- the iframe is invisible and I'm only using it to run javascript within the security context of a site on a different hostname from the parent page.

So at this point I'm stumped. Got any ideas? I want to make sure I'm not overlooking an easy solution before giving up.

A: 

This really needs to be done by the browser. Efforts around this issue go back to 2007 or so:

This functionality is needed for all DOM elements. Ie, you should be able to specify that javascript under any DOM element should not be executed. You should also be able to specify that resource requests under a certain DOM element are restricted to certain domains, etc. Together, these would help mitigate XSS and CSRF attacks.

In any case, don't hold your breath.

Chase Seibert
+1  A: 

setting document.domain disables the ability to make XmlHttpRequest calls

That is not true, I have done it many times. If you control both domains, why, you can use it.

Also, if you are comfortable restricting browsers to FF3+ and IE8+ (yes, the one you are thinking about does it too), you can use postMessage, a very cool HTML5 feature that lets you pass messages from window to window.

Victor
Unfortunately, I need to support IE6, so I can't rely on postMessage.
Justin Grant
I found multiple online posts saying that XmlHttpRequest stopped working after setting document.domain, but after testing it myself it's clear you are correct-- even on IE6 you can still call XmlHttpRequest as long as you use a relative URL. +1 for you! Note that the host you connect to is always the origin host, not the document.domain host. I'm not sure if this is enough to let me do the same-top-level-domain validation that I want to do, though.
Justin Grant