On my site, I have an iframe that displays content which is at least in part user-generated, but also needs to have scripts act upon it. Right now I communicate with the frame by targeting its contentWindow property, which is nice since the actual script runs outside (in a technical sense) of the frame itself.
However, what I'd really like to do is shut down all scripts inside of the frame entirely, without stopping scripts that originate on my parent frame from acting on the frame's window.
I tried using the sandbox property in various forms, but it seems to be an all or nothing deal. I also tried sanitization, but part of the user-generated content is fully-formed HTML, which is at best enormously difficult to clean.
How can I stop all scripts in an iFrame (same-domain) while still giving the top frame scripting access?
Related
I'm creating a web-based game. As a part of it, the player must go to the home page of a website, and follow a series of link until he reaches to the "destination page" in the minor time possible. Think of it as a sort of link treasure hunt.
In order to control the game, I created a page with a javascript timer on the top, and an iFrame showing the website to surf (which is not mine and I have no control over it).
However this has a huge fault: it is not possible to detect the current cross-domain URL of the iFrame, so my page cannot know when the user has arrived to the destination page and stop the game.
Is there any alternative way I could achieve this?
Is there any alternative way I could achieve this?
No, there is not.
The Same Origin Policy completely prevents you from accessing properties of any window object that displays content from another domain.
(If one was a subdomain of the other, then document.domain would help. But from your problem description it doesn’t sound like that was the case.)
And besides the technical issue: Generating traffic and clicks (that will skew their statistics/analytics) on a site that you don’t own, just for the purpose of being able to present your own game, would be rather unfair (aka a “dick move”.)
You can wait upto the contentWindow of the iFrame is resolved and you have a reference to the iFrame's window, after you changed the source pragmatically.
once you have that, you can add a onload handler on iFrame's <body> and inject some postMessage call inside that handler, so once the body is loaded of the iFrame's window it wil call postMessage from the onload handler of body and it will notify your outer window, of-course you have to add message listener in outer window using window.addEventListener("message", callback)
My website offers rich content to users. I often subscribe to third party vendors whose content I embed in my pages. How can I safely embed external domain's content on my webpage in an iframe without worrying that they won't be able to bust out of frame. They won't do it purposely (without risking their clientage/reputation). However, since they almost always are small shops, they become a juicy targets for an attacker who wants to deface/redirect my website.
I am not asking how can I prevent an iframe to access parent frame's DOM, which I know it can't. I am asking how can we prevent an iframe to stop doing something like the following (which doesn't require access to parent's DOM):
top.location=url
Is there a header (something similar/opposite to X-Frame-Options) which I can use on my parent page to ensure that the iframes I embed can't bust out? Remember, I can't ask vendors to add headers/scripts to their pages. They never purposely want to do nefarious things to my page. The scenario I am trying to cover is the one when they get hacked.
As noted in the comments, sandbox attribute can prevent the script inside the iframe to access the windows top.href, location.href and similar methods. This will do what I want to achieve.
From w3schools:
When the sandbox attribute is present, and it will:
prevent the content to navigate its top-level browsing context
I'd like for the opener of an iframe to be able to detect each time the user changes pages within that iframe. Using jQuery, I can detect each time a page finishes loading within an iframe via the following:
$('#myIframe').on('load', function() {/*do stuff*/});
However, I'd also like to detect (in the iframe opener) each time a page starts loading within that iframe.
Note: The content that is displayed in the iframe is from a third-party site, so I don't have the ability to insert code there so that the iframe can explicitly alert the opener.
Does anyone know of an event that is fired when a page begins loading? I'm not having much luck finding anything via Internet searches, as most people seem to only be interested in detecting when the iframe has finished loading.
It seems unfortunately that the only way to be sure it will work in most browsers is to use the <iframe onload="myonloadscript();"
The window.onload event of the main page will tell you when the iframe has loaded and you can be sure it has begun it's request for it's src page
Edit:
Just copying it from an article (Their are hacks for this)
doing this cross-domain? Not so easy. You’ll get something along the line of: Child document does not have the right to access parent document. In fact there is a lot of documentation on the web about how to achieve it, but the problem is that it is often outdated, with solutions that often only works in a couples of browsers.
I was studying how Disqus and other embedded wigets are implemented, and I came to realize that they don't use an enclosing iframe where all their widget is run. What they do is to append elements dynamically to the embedding page through JavaScipt and then run almost every form or button in some iframe. What's the point of doing this? Couldn't they just wrap everything in an iframe and then change the parent window URL (to allow navigation) through some kind of cross-domain messaging system such as easyXDM? Can anybody point out some benefits that arise from having some elements not inside an iframe?
Code inside an iframe may not be able to set cookies as browser thinks it is an advertisement.
Iframe content cannot control the size of the outside iframe, so iframe needs to be created with javascript and javascript needs to be loaded externally so that external site has total over iframe size.
I am developing a webpage which our customers want to insert on their websites by wrapping my page in an iframe (cross domain). I don't need to interact with the parent or know anything about whats outside the iframe.
I am using HTML, CSS, Javascript and Webservices.
Question: How am I limited inside an iframe compared to if my page was running outside the iframe?
You're not. Any JS linked within the iframe from your domain will act in the context of the iframe. Aside from being crammed into an unusual container it should work the same as it would if it was loaded independently.
If your needs should change however, there are ways to send signals between parent frame and iframe if both pages have JS written to cooperate. There's methods using the # in URLs which can be read by the parent and don't force page reloads and I believe they share the window.resize event which can be fired manually without actually resizing the window.
UPDATE: There are far better ways to communicate between cross-domain iframes now than there used to be. Naturally you'll still require cooperating JS on both ends but you can use window.postMessage rather than triggering messages via window.resize and data after a hash symbol in the URL. That was a cool trick though.
When creating links you should have in mind to maybe use the target-attribute of the a-tag if you want to create a link for the parent window. Otherwise the new page would be loaded into the iframe.