Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cross domain postMessage, identify iFrame

I use postMessage to send events from an iframe to it's parent document. I have control over both sides but the content comes from two different domains.

enter image description here

My simple problem is, that i can not identify the iFrame inside of it's parent callback method. The implementation looks like this:

In the iFrame:

parent.postMessage(JSON.stringify({action: "closeView" }),'*');

In the parent window:

window.addEventListener('message',function(event) {
if(event.origin !== 'https://example.com')
    return;

    // Parse message back to json
    var messageObject = JSON.parse(event.data);
    var source = event.source;
    /* this is returning: Window -URL- */
    console.log( source );
    /* This will throw Permission denied, although this code is inside of "parent" */
    console.log(source.parentNode);
},false);

I want to identify a certain parent element of the iframe, which is (logically) inside of the parent document.

When i try to use event.source.parentNode or some jQuery on said object, Firefox says, i can not do this to prevent XSS, error: Error: Permission denied to access property 'parentNode'

How can i get the parent element of the iFrame, that triggered the postMessage event listener?

like image 301
Nico O Avatar asked May 13 '14 11:05

Nico O


People also ask

How do you know if an iframe is cross domain?

to select the iframe with querySelector . Then we define the canAccessIFrame function that checks if the iframe has the contentDocument property defined. If it's defined then it's not a cross-domain iframe or it's cross domain and cross domain is allowed. Otherwise, false is returned.

Does postMessage work cross domain?

PostMessage() is a global method that safely enables cross-origin communication. It's a lot like Ajax but with cross-domain capability. We'll give it a whirl by setting up two-way communication between a web page and an iframe whose content resides on another server.

How do I access cross domain iframe?

To access cross-domain iframe, the best approach is to use Javascript's postMessage() method. This method provides a way to securely pass messages across domains.


1 Answers

you can use window names for this, as they pass from iframe tag to iframe context.

parent doc:

<iframe name=fr2 src="data:text/html,%3Chtml%3E%0A%20%3Cscript%3E%20parent.postMessage%28%7Bname%3A%20window.name%7D%2C%20%22*%22%29%3B%3C/script%3E%0A%3C/html%3E"></iframe>
<iframe name=fr3 src="data:text/html,%3Chtml%3E%0A%20%3Cscript%3E%20parent.postMessage%28%7Bname%3A%20name%7D%2C%20%22*%22%29%3B%3C/script%3E%0A%3C/html%3E"></iframe>

<script>onmessage = function(e){ // use real event handlers in production
       alert("from frame: " + e.data.name);
 };</script>

iframe doc:

<html>
 <script> parent.postMessage({name: name}, "*");</script>
</html>

which alerts "fr2", then "fr3". you can then easily use the name attrib to find the iframe in the parent DOM using attrib CSS selectors.

illustrative demo of window.name+iframe concept: http://pagedemos.com/namingframes/

this painfully simple approach is also immune to issues arising from same-url iframes.

like image 50
dandavis Avatar answered Sep 23 '22 14:09

dandavis