santubangalore
santubangalore

Reputation: 792

How to change sandboxing flags of iframe

I have an iframe in my aspx page. the code for that is:

<iframe style="height: 513px; width: 1071px" id="iframe1" sandbox="allow-same-origin allow-scripts allow-popups allow-forms" src="paymentprocess.aspx"></iframe>

the sandbox attributes are necessary for stopping the iframe page to take up entire window. after the payment the response page loads in iframe because of automatic redirection. I want to change the attributes of iframe thru javascript so that entire windows shows the response page. I am getting an error message in javascript console.

the frame attempting navigation of the top-level window is sandboxed, but the 'allow-top-navigation' flag is not set.

I am using this code:

 if (top != self) {
     top.location = self.location;
 }

but that is throwing the above mentioned error in console.

Please someone help me how to change the attributes of iframe of parent window from child page (in this case confirmation page)

Upvotes: 3

Views: 9180

Answers (1)

Ramesh
Ramesh

Reputation: 1287

I am assuming that the page you are loading this iframe within and the content you are loading inside the iframe are on different domains (Interpreted from paymentprocess.aspx). If this is the case you can not directly handle parent document because of cross origin policy. But still you can post message to the parent, handle this message in parent and set this extra flag in iframe attributes with set attribute.

Example code:

from iframe :

window.parent.postmessage("ChangeIframeAttributes", *);

inside your parent document:

window.addEventListener('message', function (event) {

    if (event.data === "ChangeIframeAttributes") {
      document.getElementById("iframeId").setAttribute("property","value");
    }

}, false);

In case you are on the same domain, you can access parent document with window.parent.document, fetch the element from document object and setAttribute.

Update:

I have tried just setting the attribute using window.parent and attribute gets update but the problem still persists while changing top.location because iframe is already loaded and attribute modification will not be effected unless nested browsing context of the iframe is navigated.

From w3c,

http://www.w3.org/TR/2011/WD-html5-20110525/the-iframe-element.html

These flags only take effect when the nested browsing context of the iframe is navigated. Removing them, or removing the entire sandbox attribute, has no effect on an already-loaded page

If the allow-scripts keyword is set along with allow-same-origin keyword, and the file is from the same origin as the iframe's Document, then a script in the "sandboxed" iframe could just reach out, remove the sandbox attribute, and then reload itself, effectively breaking out of the sandbox altogether.

Generally speaking, dynamically removing or changing the sandbox attribute is ill-advised, because it can make it quite hard to reason about what will be allowed and what will not.

From my understanding, two workable options.

  1. set the flag from beginning. (which is not a better way of doing it)
  2. use post message by sending url and setting window.location on parent.

Pseudo code :

on main window:

<script type="text/javascript">
function f()
{
    var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
    var eventer = window[eventMethod];
    var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";

    // Listen to message from child window
    eventer(messageEvent,function(e) {
        var key = e.message ? "message" : "data";
        var data = e[key];
        window.location = data;

    },false);
}
</script>
<body onload="f()">

<iframe id="iframeId" src="testiframe.html" sandbox="allow-same-origin allow-scripts allow-popups allow-forms">
</iframe>
</body>

on iframe :

<script type="text/javascript">
var callParent = function () {

    window.parent.postMessage(" " + self.location, '*');

};
</script>
<button onclick="callParent()">set parent attribute<button>

Second approach i have tested with the above code and it works.

Hope this is helpful.

Upvotes: 6

Related Questions