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
Related
I have an iframe.
I want to prevent access from the parent document into the iframe from css selectors and other manipulation.
How can I secure it?
You could kill a goat under the light of a full moon inside a pentagram made of salt. If you did that, css or js wouldn't be able to affect the contents of an iframe.
They wouldn't affect them if you didn't either.
You have to explicitly allow sites to interact with the contents of an iframe, either by setting up an api like this, or by setting up cors headers to allow interaction. According to other answers on this site, if the iframe and parent have the same domain, cors rules don't apply, so changes can be made. If you are embedding an iframe from your site on your site, you should probably trust your own code.
If you are asking how to prevent users from using the developer tools to mess around with your iframe contents, you can't. There are all sorts of things that website designers have tried to do to keep me from looking at their source. I've never found one that can keep me out.
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?
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.
I have to include an external whitelabel site within an iframe on my page. There are numerous pages on the external site and they vary considerably in height.
I need to adjust the height of my iframe to accommodate this.
I can get the height of the first page loaded into the iframe (using PHP), but no way of getting subsequent page heights because no way of knowing what the url/location changes to in the iframe.
As this is an external url in the iframe the usual security limitations apply, therefore ALL solutions must come from the parent frame. Solution must be workable on FF and IE at least.
The only think I can think of is to test whether the scrollbars are visible on the iframe, but this is seemingly impossible in these circumstances.
If anyone can prove me wrong, or has any other javascript/ajax/php cross-browser solution I'd love to hear it.
It is not possible to do this because of the browser's security model. If it was possible, that would be a security problem and would have to be fixed.
Although letting the embedding site know the height of a third party webpage when embedded in the page seems harmless, this can leak information to the embedding site that the browser's user wants to keep private. For example, http://www.facebook.com/ renders differently depending on whether or not you are logged in, so if my website can work out the height of <iframe src="http://www.facebook.com/"> then I can work out whether or not you are a facebook user, something you probably don't want me to know.
The information leakage would be similar to the infamous CSS History Leak in that it would reveal information about the user's relationship with the third-party site just by "linking" to that site (in this case with an iframe instead of a link). Browser vendors had to plug the CSS History Leak, so I suspect if you could work out the height of a third party site rendered in an iframe in any browser, the vendor would have to fix that too.
The information leaked would be anything that can be inferred from the height of a page when rendered for a user using their cookies (which the browser will send even though rendering in an iframe inside a different domain's page). The specific risks depend entirely on the nature of the embedded site being "attacked". E.g. I could get an idea of how much stackoverflow activity someone visiting my site has by getting the height of https://stackoverflow.com/reputation which is different for different users.
Can the iframe access its parent if I changed its src to "about:blank" after loading it in the parent page?
Note: the iframe is in another domain not the same as the parent page.
No. If you change the src attribute of the frame to about:blank the content of that frame will be replaced with the blank document, and any javascript running inside the iframe will terminate.
If you need a way for the two to communicate, one of the ways to go is to expose some kind of JSON based endpoint that can be called from one of the domains, while the other polls for a result.
UPD: Regarding your pronto question, I would guess they don't use an iframe. Pronto is a bookmarklet, which allows code to run in the "outer" page. While I didn't verify this, I'd guess they are able to make the browser page load their JS library via an injected script element, and display their UI that way.
Generally, no. This is known as cross-site scripting (XSS) and is considered a security risk, so most browsers prevent it.