Search code examples
htmljspiframepopupx-frame-options

iframe can access element of parents with different origin(domain + port)


I know a iframe tag can access to parent element with same domain + ports. However, what if parent and iframe has different domain + port ?

i.e.

parent's domain is http://aaa.com:63342, and iframe domain is http://aaa.com:9080.(Please note that they have different ports)

Both of pages have <meta http-equiv='X-Frame-Options' content='ALLOWAll'> in their headers.

  • first, parent frame call iframe with form submit. like...
<!DOCTYPE html>
<html>
<head>
  <meta http-equiv='X-Frame-Options' content='ALLOWAll'>
  <title>ParentWindows with aaa.com:63342</title>
</head>
<body>
  <form name='form' method='post' id='form' action=''>
      <input type='text' name='greetings' value='Hello from the otherside'>
  </form>
  <script>
      document.form.target = 'iframe';
      document.form.action = 'http://aaa.com:9080//inFrame.jsp';
      document.form.submit();
  </script>
</body>
<iframe src="" name='iframe'></iframe>
</html>
  • Then a server returns like below in jsp
 <% 
  response.setHeader("X-Frame-Options", "ALLOWAll"); 
  String greetings = request.getParameter("greetings");
%>
<!DOCTYPE html>
<html>
<head>
  <meta http-equiv='X-Frame-Options' content='ALLOWAll'>
  <title>iframe with aaa.com:9080</title>
</head>
<body>
  <div>
      greetings message : <%= greetings %>
  </div>
</body>
<script>
  var div = document.createElement('div');
  div.textContent = 'Echo Hello';
  parent.document.body.appendChild(div);
</script>
</html>

It is simple version of the situation what I am in. However, when I do like this, browser console shows error like..

Uncaught SecurityError: Blocked a frame with origin "http://localhost:9080" from accessing a frame with origin "http://localhost:63342". Protocols, domains, and ports must match.

Now I am doubting with this method(calling different hosts between iframe and parent) is possible at first place... Is it possible?

How can I make this works?

Thanks a lot


Solution

  • Detour to original frame.

    something like...

    original page with aaa.com:63342/original.html is

    <!DOCTYPE html>
    <html>
    <head>
      <meta http-equiv='X-Frame-Options' content='ALLOWAll'>
      <title>ParentWindows with aaa.com:63342</title>
      <script>
        function setGreetings(greetings){
          document.getElementById('greetings').value = greetings;
        }
      </script>
    </head>
    <body>
      <form name='form' method='post' id='form' action=''>
          <input type='text' id='greetings' name='greetings' value='Hello from the otherside'>
      </form>
      <script>
          document.form.target = 'iframe';
          document.form.action = 'http://aaa.com:9080//inFrame.jsp';
          document.form.submit();
      </script>
    </body>
    <iframe src="" name='iframe'></iframe>
    </html>
    

    Then page(jsp) which imported into the original page(inside of iframe) looks like... I can call aaa.com:9080/inFrame.jsp

    <% 
      response.setHeader("X-Frame-Options", "ALLOWAll"); 
      String greetings = request.getParameter("greetings");
    %>
    <!DOCTYPE html>
    <html>
    <head>
      <meta http-equiv='X-Frame-Options' content='ALLOWAll'>
      <title>iframe with aaa.com:9080</title>
    </head>
    <body>
      <div>
          greetings message : <%= greetings %>
      </div>
      <iframe id='iframe' src="http://localhost:63342/third.html?greetings=<%= greetings %>"></iframe>
    </body>
    </html>
    

    This is the third frame aaa.com:63342/third.html, final

    <!DOCTYPE html>
    <html>
    <head>
      <meta http-equiv='X-Frame-Options' content='ALLOWALL'>
      <title>ACCESS TO TOP FRAME on localhost:63342</title>
    </head>
    <body>
    <script>
        function setGrandfather(){
            var greetings = getParams()['greetings'];
            window.top.setGreetings(greetings);
        }
    
        //parsing parameters
        function getParams() {
          var param = new Array();
          var url = decodeURIComponent(location.href);
          url = decodeURIComponent(url);
          var params;
          params = url.substring( url.indexOf('?')+1, url.length );
          params = params.split("&");
          var size = params.length;
          var key, value;
          for(var i=0 ; i < size ; i++) {
              key = params[i].split("=")[0];
              value = params[i].split("=")[1];
              param[key] = value;
          }
          return param;
        }
    </script>
    </body>
    </html>
    

    What happens here

    1. the original page has iframe which has different domain
    2. the second page(iframed in the original page) also has an iframe which has same origin with original page
    3. the second page will send data to its iframe(the third page) with post/get. I wish it could access other frame element via parent.document or iframe.contentDocument.document, but these will be blocked by SAMEORIGIN policy.
    4. In third page you can access functions and elements of the original frame since they have same origin(domain + ports).

    CAUTION

    1. frames can not communicate directly
    2. only those pages has common url, possible to set sub domain via document.domain