Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Foolproof way to detect if iframe is cross domain

Tags:

I'm trying to determine if any iframe is cross-domain or not. According to the accepted answer in this question: Detect when iframe is cross-domain, then bust out of it it says to put the code accessing the contentDocument of the iframe in a try / catch block. I tried this for a cross-domain iframe in Chrome:

try {    document.getElementsByTagName('iframe')[0].contentDocument; } catch(err){   console.log("called"); } 

and it still throws the cross-domain error and does not catch the error.

I also tried to check if the protocol + host + port of the parent page url is in the src of the iframe:

function thirdPartyIframe(iframe){   var url = document.location.protocol + "//" + document.location.hostname + (document.location.port === "" ? "" : ":" + document.location.port);   var regexp = new RegExp(url.replace(/\//g, "\\/").replace(/\./g, "\\."));   if (iframe.src === '' || regexp.test(iframe.src)){     return false;   } else {     return true;   } } 

but this does not seem to work for the first iframe on the homepage of Facebook with src equal to (it's long):

"http://www.facebook.com/ai.php?aed=AQLlH2cfdnsnLrDUVyqrQPlWpayw9N09Z_iNuhulevbeEfVa4mcVRcT8cjAZOjQb8y1QXab5Ae3aSEJx49U_Qv35rtSp1VC9cY0_CrpOjMDk40hS_Xm57A996YtRVCcWSuRZ_jZERQ_iA_E4621NAbKHT9dsB7uElkRtTvl5K-zPI0jeH-BEnlZIOXbeEdbRC6qCwoToaltolpe-Ot2KWgkfb_vBZYpzUc3jQoEHzLG6tauO9l_hkXpYpHxnt-KYFKIFZ1PgmrHgb0UcGjeKHl7yBR1AbW2n5XgdgaAhFvBjs5GZlKy566nvl8eLRA60orwkwtWYeN8-gKoAmOLm7-6minsWn8lk1h2Qn3p07HCTSnYHfv1aJ6mF5jmuzP0YYe7Ym9ZbmK-tvax4uPAQJ2OdULilKbEh8M-2V9pVY3AC228OPlrRullZuuOg8DI2A8WeMF-fbbOdOFFVCe5Gj1CaZu3LYXiqdG7mUgY6AEpk9ZzGT4fC2K8DInQo1AypCvzG64C_bEWfODeXe0aGbkWwsUUmO7E5HFg0tvZkK5IAR_xxxQ2rlf5jbcEDo_2gdIDdHe1HT75-SJLUsSA0M8EU01oNNPuWwEC2BW6inepc9QPuqeg42tcEbKLU-rIUnXDBLvgutft8azWPPQ6_LafGjCAmC9uTalagoWLLDMpQOThvPg7YeVd7qg_c9Mzn2GAfuswcxDSxyRIZo9MaOhA6mhfXeE1tmjyBBsMxnx08tO21Jsfgch59fmMxpeJzdsNMPK3FAojfglvCQ2Zrt_6ataexUB4xlM7_PhKrfBPtxb5fe2TE9-nlWruNEpoCrzI05yv4Go3CYEWHob06K_9iICfNVTFkSYGTiJnMXCy_fdgfyzUIn5QJIPRo4-Wnyg444zKAO_nyFW59LqbIanHVfFY6ybiA6KeC3meREWzTPSsrU5d_NbYHlJWb8uPNDR04jaH5e2qiYj3Y8qgLQA5m" 

My function classifies it as not a third party iframe, but Chrome still throws the cross-domain error when I access its contentDocument.

I'm looking for a foolproof, cross-browser way to do this.

like image 456
user730569 Avatar asked Sep 12 '12 04:09

user730569


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.

Is iframe cross domain?

A page inside an iframe is not allowed to access or modify the DOM of its parent and vice-versa unless both have the same origin. So putting it in a different way: document or script loaded from one origin is prevented from getting or setting properties of a document from another origin.

How do I get cross domain iframe content?

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.

Is iframe cross origin?

Cross-origin communication in between iframe and it's parent website. Yes, it's not any hack or something, but with simple functions you can communicate in between iframe and it's parent website.


2 Answers

You need to do a little more than what's in your try/catch to handle different browsers and to handle different ways that browsers deal with cross domain access:

function canAccessIFrame(iframe) {     var html = null;     try {        // deal with older browsers       var doc = iframe.contentDocument || iframe.contentWindow.document;       html = doc.body.innerHTML;     } catch(err){       // do nothing     }      return(html !== null); } 

In your example, this would be:

var accessAllowed = canAccessIFrame(document.getElementsByTagName('iframe')[0]); 

Working demo: http://jsfiddle.net/jfriend00/XsPL6/

Tested in Chrome 21, Safari 5.1, Firefox 14, IE7, IE8, IE9.

like image 149
jfriend00 Avatar answered Oct 06 '22 08:10

jfriend00


A more shorter and more readable function for modern browsers

function canAccessIframe(iframe) {   try {     return Boolean(iframe.contentDocument);   }   catch(e){     return false;   } } 

Tested with Chrome 79 and Firefox 52 ESR.

Explanation: you can check any iframe property that is not accessible cross-origin and convert to boolean. example: contentDocument / contentWindow.document / location.href / etc.

Boolean docs: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean

like image 33
crisc2000 Avatar answered Oct 06 '22 08:10

crisc2000