Access parent from iframe even though domains don't match? - javascript

I have a javascript script that is being run from within an iframe that is trying to access the parent but I'm getting the following error:
Unsafe JavaScript attempt to access frame with URL mysite.com from frame with URL myothersite.com?. Domains, protocols and ports must match.
The iframe html is on a different domain but I didn't think that would matter. This is the code that is generating the JS error:
var parent_site = parent.document;
Is there a way around this?

If the parent domain is a trailing part of the iframe domain (i.e., iframe is child.parent.com and parent is parent.com) you can set the domain of the iframe document with document.domain = "parent.com" and avoid the problem.
If the domains of the parent and the iframe are unrelated there is no way to work around it.

Do some research on CORS (Cross-origin resource sharing): http://www.w3.org/TR/cors/
You essentially need to add this to your .htaccess of the parent domain:
Header set Access-Control-Allow-Origin *
Header set Access-Control-Allow-Headers x-requested-with
Ideally you'd replace the * with the domain(s) for which you want to allow access.

Related

How to get URL, that browser uses for CSP

I'm creating a script, that embed iframe with my site to client's site, but I want to limit access to this feature.
I added 2 headers to the server responses
Content-Security-Policy: "frame-ancestors: example.com"
X-Frame-Options: ALLOW-FROM example.com
It works, but X-Frame-Options doesn't support multiple domains, so I added a GET-param to the iframe URLs, that contain frame ancestor URL
And when http://example.net requests mysite.com/embed/?from=http://example.net I check the whitelist and send this domain in headers
My problem is obtaining a real page origin, that browser uses to compare with the headers.
I tried location.origin and document.referrer but both return wrong values when I request iframe from iframe.
For example http://jsbin.com. I can't find way to obtain real URL in sandboxed code, it's always http://null.jsbin.com. But for Content-Security-Policy a browser uses http://jsbin.com/

what is the scope of document.domain()?

I understand if we have payment.example.com and news.example.com and they both set document.domain to exmaple.com they can communicate. However, what if en.news.example.com opt-in and set document.domain=example.com? is it also possible to communicate?
Document.domain
Gets/sets the domain portion of the origin of the current document, as used by the same origin policy.
The same-origin policy restricts how a document or script loaded from one origin can interact with a resource from another origin. It is a critical security mechanism for isolating potentially malicious documents.
Example :
// for document www.example.xxx/good.html,
// this script closes the window
var badDomain = "www.example.xxx";
if (document.domain == badDomain)
window.close(); // Just an example - window.close() sometimes has no effect.
var domain = document.domain;
Changing the value of this property is the easiest way to work around the limitations that the same origin policy applies when your pages are on different sub-domains of the same site. While JavaScript would normally consider pages from blog.example.com and from forum.example.com to be from different origins and so not allow JavaScript from one to interact with web pages from the other, you can resolve this particular restriction by setting the document.domain in both pages to the same value. By setting the document.domain to the shortest version of your domain name in all of your scripts you would allow your JavaScript to communicate across all of the pages of your site regardless of protocol, sub-domain or port.

How to resize an iframe (HTTPS) from a site (HTTP) under the same domain

I have a site that host some public content: https://secure.example.com/PublicContent.html. I am rendering it through an iframe on an unsecured site: http://public.example.com. I have both pages setting document.domain = "example.com";.
If I load public.example.com using HTTPS, I can have the iframe resize correctly using the onload attribute:
onload="this.style.height = this.contentWindow.document.body.scrollHeight + 'px';"
However, if I load public.example.com without HTTPS, I get Access is denied. Any ideas how to get this to work on HTTP?
Not possible if you're using this.contentWindow
Same-origin policy: https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy
Two pages have the same origin if the protocol, port (if one is specified), and host are the same for both pages.
To share information between the same domain no matter which protocol used, you might want to take a look at cookies. https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy#Cross-origin_data_storage_access.
Also, used this lib to solve a similar issue: https://github.com/davidjbradshaw/iframe-resizer

javascript iframe: accessing http from https

I have a page that has an iframe which loads html template from amazon aws s3 bucket. In the iframe, I want to take the link of the parent window, then add some parameters.
E.g: My parent window has the link http://xx.xx.x.xxx:8088 . I want to take this url, apprend "#abc/edf" and redirect to that page. But I cannot because my iFrame has url https://bucketName.s3.amazonaws.com
The error I get is
Uncaught SecurityError: Blocked a frame with origin "https://bucketName.s3.amazonaws.com" from accessing a frame with origin "http://xx.xx.x.xxx:8088". The frame requesting access has a protocol of "https", the frame being accessed has a protocol of "http". Protocols must match.
The javascript I used to redirect to another page from within an iFrame
function navigateTo(e){
var destination = e.data.destination;
var url = window.parent.location.host;
window.parent.location.href = url+destination;
}
$("#button").click({destination: "/#abc/edf"}, navigateTo);
html
<div id="button">Redirect to another page</div>
I cannot use absolute path for a reason. The parent window link will change somehow. I think the best solution is to take the parent url and append the parameters that I want. How can I make this happen without getting the security error?
Short answer is "you can't."
Browser security model precludes cross-domain and cross-protocol scripting from the client side. Your embedded iframe under the https protocol is not allowed to access (not even read) its parent's non-https context.
To do what you want, both contexts must agree on both domain of origin and protocol in order to interact on the client side.

Unsafe JavaScript attempt to access frame with URL - in the same domain

I'm trying to access to the URL of the parent window from an iFrame but I got an error on my server:
Unsafe JavaScript attempt to access frame with URL
http://www.domain.com/folder/ from frame with URL
http://www.domain.com/folder/file.html. The frame being accessed set
'document.domain' to 'domain.com', but the frame requesting access did
not. Both must set 'document.domain' to the same value to allow
access.
I'm in the same domain so I don't understand why I get this error.
For your information everything works good in localhost.
Thanks for your help.
OK I found the solution.
I put this code and that works:
document.domain = 'domain.com';

Categories