Get top href and innerHTML from within an iframe - javascript

Is there any way to grab any information from the top from within an iframe on a separate domain? Somebody has tasked me with validating that their advertising is not next to things like pornography, etc... but their ads are always inside an iframe on publisher sites.
Interestingly, when I put twitter.com in an iframe, they have iframe busting technology turned on - like so:
<script type="text/javascript">
//<![CDATA[
if (window.top !== window.self) { setTimeout(function(){document.body.innerHTML='';},1);window.self.onload=function(evt){document.body.innerHTML='';};}
//]]>
</script>
What strikes me is that, as a different domain, they still have the ability to get window.top. However, when I try to extend this functionality to window.top.location or window.top.href to get the URL of the top window, I get
uncaught exception: [Exception... "Component returned failure code: 0x8007000e (NS_ERROR_OUT_OF_MEMORY) [nsIDOMNSHTMLDocument.write]" nsresult: "0x8007000e (NS_ERROR_OUT_OF_MEMORY)" location: "JS frame :: http://tester.tester.com/iframe3.html :: <TOP_LEVEL> :: line 9" data: no]
http://tester.tester.com/iframe3.html
Line 9
which is really just a permission error that is being misreported by Gecko (I think).
Any thoughts on this? Is an equality statement available because the iframe doesn't actually get the data while getting the data itself is not available?
Any information I can get would be better than nothing, so please feel free to put in partial answers. Thanks.

Is an equality statement available because the iframe doesn't actually get the data while getting the data itself is not available?
It's an ancient quirk of JavaScript that you can always get the ‘window’ object of a cross-domain frame/iframe/parent/opener. But — for obvious security reasons — you can't access most members of the object. There have occasionally been ways to circumvent these restrictions in the past due to browser bugs, but nothing you can rely on.
Pretty much the only thing you can usefully do with an unknown window object is check to see if it's the same object as some other known window object, such as the current one.
If you want to test whether an unknown window is at least inside your own domain, you can try to access otherwindow.location inside a try...catch block.
Is there any way to grab any information from the top from within an iframe on a separate domain?
No, but you can record the ‘Referer’ header at the HTTP server end to see what page included the <iframe>. But surely your advertising network should be doing this for you already anyway?
if (window.top !== window.self)
Curious; window.self is the same thing as window; I don't know why you'd ever use the longer version. The shortest idiom for this test is:
if (top!==self)
which works as long as you aren't defining any other variables called ‘top’ or ‘self’.

No there's not. It's due to Cross-site scripting attacks.

Related

How to call javascript after frame is fully rendered?

I am looking for a way to modify an iFrame attribute (a textbox value actually). The iFrame is on another domain and I do have access to it. From what I understand I must do that after the entire page (iFrame included) is rendered. I tryed something like that:
<script type="text/javascript">
$(window).load(function() {
alert("test");
d = document.getElementById("myframe");
d.contentWindow.document.getElementById("frametxtbox");
});
</script>
But I always get the following error:
Cannot call method 'getElementById' of undefined
I also noticed that the alert pops up BEFORE the iFrame is rendered, so I think my script is executed before page has access to frame values and, therefore I get the error. I have very few knowledge of web-related programming (always worked on backend side) so forgive me if my question maybe makes no sense.
If the iframe points to another domain, it'll be subject to same origin policy. This means that before you try to access its document you'll have to check the wiki and relax the policy (check the link for details). After that you'll need to bind ready event to the iframes document, rather than your main page doc.
$(window.frames['myframe'].document).ready(function() { alert('moo'); });
See if this helps :)

Call Javascript Function in Child iFrame with Cross Domain site but Same location JS file

I am trying to do the following:
Main document calls a function in iFrame whose URL is from a different location but the Javascript function I'm trying to call loaded from the same domain as the main document.
Is there any way to do this?
To clarify:
Main document: http://www.main.com
iFrame document: http://www.example.com
JS function i'm calling in iFrame is at http://www.main.com/js/script.js
I'm getting
Permission denied to access property 'js_function'
When doing
document.getElementById("iframe").contentWindow.js_function(n)
Even though the script is hosted on main.com it is executed in the context of example.com and therefore is considered to be part of example.com ... and therefore has no access to variables or functions in the main.com window. You can hack around this with various cross domain communication hacks (or you can ignore IE < 8 and use window.postMessage by itself).
SEE ALSO: http://stevehanov.ca/blog/index.php?id=109
I see what you're doing. There was a "hack" that made use of two iframes (if I remember correctly).
Both that hack and the one you mention here are awfully obscure, and I wouldn't be surprised if they have been locked down knowingly.
The best fix I can think of is to load the code for js_function() in the main window (outside of the iframe).
Can you be more specific on what the JS code does? I may be able to help better.
Use easyXDM's RPC feature, it combines XDM with RPC.
An example of this can be seen here: http://consumer.easyxdm.net/current/example/methods.html

Document.domain not functioning as I'm expecting

I'm looking to access an API via a proxy located at bar.domain.com. And I'm accessing it via a script which is located on foo.bar.domain.com. So I ran up against the same origin policy, of course.
At the top of the first script loaded on foo.bar.domain.com, I set document.domain = "bar.domain.com".
In the inspector, if I pause the execution immediately after this line and check document.domain, it returns bar.domain.com. Same with pausing just before the .ajax fires, and same with checking after all javascript has run.
Unfortunately, I'm still getting: Origin http://foo.bar.domain.com is not allowed by Access-Control-Allow-Origin.
I wish I could give a live example, alas, I was asked not to :/
Any ideas on how I could fix or debug this? Thanks so much for any help you could give.
I think that both sites need to set document.domain to "bar.domain.com", because both pages have to explicitly indicate their willingness to interoperate. It doesn't matter that the "bar.domain.com" page already has the same string for document.domain — it still must set it explicitly.
Here is an MDC page with some explanation.

Permission issues checking if parent site is my parent domain within iframe

I've read several of the questions on this but am still a little confused.
For example: OK, I can't post examples because of hyperlink limitations
Here is my exact situation.
I have a site at mydomain.com
One of the pages has an iframe to another page at sub.mydomain.com
I am trying to prepare an onload script that if the page is not in an iframe or the parent domain of the page containing the iframe is not mydomain.com then redirect to mydomain.com.
After the initial permission issues I realised the problem with sub domains counting as separate domains.
One of the posts above says that "could each use either foo.mydomain.com or just mydomain.com"
So I tried (for testing):
onload="document.domain='mydomain.com';alert(parent.location.href);"
This produced the error (http replaced with lar
Error: Permission denied for <http://sub.mydomain.net> (document.domain=<http://mydomain.net>) to get property Location.href from <http://mydomain.net> (document.domain has not been set).
Source File: http://sub.mydomain.net/?pageID=1&framed=1
Line: 1
Removing the alert produces no errors.
Maybe I am going about this the wrong way since I do not need to interact with the parent just read its domain if there is one.
A nice simple top.domain. For read only there must be a way so that people can prevent their own pages being used within other people's sites.
You can't (easily) do this because of security restrictions.
This answer from #2771397 might point you in the right direction.
OK, while looking at the error console I still had open when I got home a wee lightbulb lit up. I am pretty new to javascript (can you tell ;) but I thought "If it has try/catch"...
well here is a hack at least to get the name of the top domain and an example of how I will use it in my site to show content only if the page is a frame in the correct domain.
Firstly the header will have the following partially PHP generated function:
function getParentDomain()
{
try
{
var wibble=top.location.href;
}
catch(err)
{
if (err.message.indexOf('http://mydomain.com')!=-1)
{
createCookie('IAmAWomble','value')
}
}
}
Basically the value will be something based on the PHP session I think. This will be executed at page load.
If the page is not within the proper site or if javascript is not enabled then the cookie will not be created.
PHP will then attempt to read the correct value from the cookie and show the content or an error message as appropriate.
I do see a slight flaw in this for first visit since page load will run after PHP has generated the content but I'm sure I can work around this somehow. I thought I'd post because this is at least what I was initially asking for and that is a way to read the URL of a parent site if it is in a different domain to the site in the frame.
IIUC you want to use the window.parent attribute: “A reference to the parent of the current window or subframe.”
Assumably, window.parent.document.location.host contains the container page URL domain name.

Firefox Error: Permission Denied to get Window.Document

I have a standard 3-frame layout; "fnav" on the left, "fheader" at the top and "fcontent" below the header. All files are located locally on the hard drive.
This is the JS function that is throwing the error:
function writeHeaderFrame() {
try {
var headerFrame = window.top.frames['fheader'];
var headerTable = document.getElementById('headerTable');
if (headerFrame && headerTable) {
headerFrame.document.body.style.backgroundColor = "Black";
var headerFrameBody = headerFrame.document.documentElement.childNodes[1];
headerFrameBody.innerHTML = headerTable.innerHTML;
} else if (headerTable) {
// there is a headerTable, but no headerFrame
headerTable.style.display = 'inline' // show the headerTable
}
} catch (e) { alert('from header.js, writeHeaderFrame(): ' + e.message); }
}
Clicking on a link in fnav (or initially loading the frameset) loads content into fcontent, then a JS file in fcontent loads the "header" frame... or it is supposed to, anyway. The Javascript runs fine initially, but whenever a link is clicked I get the following error:
Permission Denied To Get Window.document
I am unable to determine why. Any and all suggestions would be appreciated.
First off, please post the code being run when you click those links, and their html.
secondly, did you have a typo there? Window.document should be window.document, should it? (lowercase w)
Edit response to changes in OP question
Without the html it's a little hard to say, but If I were taking a stab in the dark, I'd say this line:
headerFrame.document.body.style.backgroundColor = "Black";
is causing the error. It looks like headerFrame is on a different domain and you don't, for security reasons, have permission to modify the contents of that frame. Of course, some of the following lines will also have the same issue.
Also see http://userscripts.org/topics/25029 and http://www.webdeveloper.com/forum/showthread.php?t=189515 for similar cases.
Edit 2
From Mozilla Development Center
Note: Firefox 3 alters the security for windows' documents so that only the domain from which it was located can access the document. While this may break some existing sites, it's a move made by both Firefox 3 and Internet Explorer 7, and results in improved security.
(see https://developer.mozilla.org/En/DOM/Window.document)
I would guess you're trying to manipulate the window or document from a different origin. HTML5 (and all modern browsers, even IE :D ) enforce (or attempt to enforce) what is called "The Same-Origin Policy". Basically JS from one origin cannot interact with the DOM of a document or window from a different origin.
What is an origin? At a basic level you could substitute domain for origin and almost be right, but the full set of rules are
You must have the same domain
The same port (eg. code on example.com:80 cannot reference the DOM of a page a example.com:8080)
The same protocol (eg. http://example.com is a different origin from https://example.com)
lastly, redirects also matter so (http://example.com -> http://example.com/?redirect=http://evil.com with the server responding with a 3xx redirect to http://evil.com will result in a different origin)
In all liklihood firefox has merely tightened up one area where they did not apply the same origin policy in the past.
Apparently, the user in question updated his installation without changing the following setting to "false", which allows local documents to have access to all other local documents.
pref("security.fileuri.strict_origin_policy", true);
Which explains why I was unable to duplicate the error on my machine.
Many thanks to all for your assistance.
Have you tried installing Firebug and figuring out which line is throwing the error? I'm guessing that since the question is tagged Firefox you are seeing this occur in it.
It'd be most helpful if you could post a template HTML page using this Javascript.
Is the script/frame pages all on the same domain? If not, this is expected. You can't access window.document from another window if they are not on the same domain.

Categories