Internet Explorer 7 blocks cross-domain iframe to parent communication

A new security setting in Microsoft Internet Explorer 7 has been causing problems with requests between iframe and parent. There is a security setting in the Internet options called “Navigate sub-frames across different domains”, which in IE6 was set to “Enabled” under Medium security, but is set to “Disabled” in IE7 by default.

An example of the type of communication that is blocked is shown here:

The container page sends a message to Page 1, in Domain A: “Change your location to Page 2”. In IE6, this is not a problem. But in IE 7, it is allowed.

According to Microsoft:

This option controls whether readers of a Web page can navigate the sub-frame of a window with a top-level document that resides in a different domain. This option has the following settings:

  • Disable, which allows users to navigate only between Web page sub-frames that reside in the same domain.
  • Enable, which allows users to navigate between all Web page sub-frames, regardless of the domain, without being prompted.
  • Prompt, which prompts users to choose whether to navigate between Web page sub-frames that reside in different domains.

theIssue.jpg

This new setting causes problems for a lot of sites that use communication across domains.

Sites that use a page in one domain to display the data, where the authentication is handled by a site in a different domain, displayed in an iframe would be affected. Many ajax sites use “fragment identifiers” for communication across domains.

According to the Tagneto blog:

A page is served from a different domain than the URL for an iframe in that page. Normally cross domain, cross frame communication is prohibited for security reasons. However, the two frames can communicate with each other by using fragment identifiers (the hash part of an URL, like http://some.domain.com/path/to/page.html#fragmentIdentifier).”

A site that I run uses cross iframe/cross-domain communication to launch and track a quizzing application which runs on one server from within an elearning application in another domain. I may have a partial solution to this issue.

My site is located in Domain “A”. Several pages within the site contain quizzes embedded in iframes. the quizzing application is located in Domain B.

The final page of each quiz transmits the user’s score back to the main site by communicating up the frame tree to the parent page of the iframe, and across domains.

Normally, clicking the final “Transmit Score” link at the end of the quiz sends a URL like this:

http://www.domainA.com?score=50&max=100

to the parent page of the iframe. The parent page receives the score and max score at the end and processes that information as required. What happens in IE7, though, is that the browser ignores the targeting to the parent page and opens the requested URL in a new window. This breaks communication because the new window is not in the correct spot in the frame tree.

My solution is, instead of communicating directly up to the parent page from Domain B, to instead redirect the Domain B page to a “redirector” page in Domain A. Then use THAT page to relay the data up the frame tree, to the parent page in Domain A. (Fortunately navigating between two pages in the same domain is still legal!)

All the redirector page contains is some javascript that parses the URL and sends it on up to the correct page:

<script>
 
//this provides a function to parse the query string for various parameters. 
    var qsParm = new Array();
    function qs(){
var query = document.location.search.substring(1);
var parms = query.split('&');
for (var i=0; i<parms.length; i++) {
 var pos = parms[i].indexOf('='); 
    if (pos > 0) {
var key = parms[i].substring(0,pos);
var val = parms[i].substring(pos+1);
qsParm[key] = val; 
  }//end if
                        }//end for
             }//end function
                        
             qsParm['home'] = null;
             qs();
      if (qsParm['home'] != null ){  parent.location.href=qsParm['home']+"&Max="+qsParm['Max'];    }
       else alert("some kind of warning goes here");
</script>