Get current iframe from page with JS [duplicate] - javascript

Okay, I have a page on and on this page I have an iframe. What I need to do is on the iframe page, find out what the URL of the main page is.
I have searched around and I know that this is not possible if my iframe page is on a different domain, as that is cross-site scripting. But everywhere I've read says that if the iframe page is on the same domain as the parent page, it should work if I do for instance:
parent.document.location
parent.window.document.location
parent.window.location
parent.document.location.href
... or other similar combos, as there seems to be multiple ways to get the same info.
Anyways, so here's the problem. My iframe is on the same domain as the main page, but it is not on the same SUB domain. So for instance I have
http:// www.mysite.com/pageA.html
and then my iframe URL is
http:// qa-www.mysite.com/pageB.html
When I try to grab the URL from pageB.html (the iframe page), I keep getting the same access denied error. So it appears that even sub-domains count as cross-site scripting, is that correct, or am I doing something wrong?

Yes, accessing parent page's URL is not allowed if the iframe and the main page are not in the same (sub)domain. However, if you just need the URL of the main page (i.e. the browser URL), you can try this:
var url = (window.location != window.parent.location)
? document.referrer
: document.location.href;
Note:
window.parent.location is allowed; it avoids the security error in the OP, which is caused by accessing the href property: window.parent.location.href causes "Blocked a frame with origin..."
document.referrer refers to "the URI of the page that linked to this page." This may not return the containing document if some other source is what determined the iframe location, for example:
Container iframe # Domain 1
Sends child iframe to Domain 2
But in the child iframe... Domain 2 redirects to Domain 3 (i.e. for authentication, maybe SAML), and then Domain 3 directs back to Domain 2 (i.e. via form submission(), a standard SAML technique)
For the child iframe the document.referrer will be Domain 3, not the containing Domain 1
document.location refers to "a Location object, which contains information about the URL of the document"; presumably the current document, that is, the iframe currently open. When window.location === window.parent.location, then the iframe's href is the same as the containing parent's href.

I just discovered a workaround for this problem that is so simple, and yet I haven't found any discussions anywhere that mention it. It does require control of the parent frame.
In your iFrame, say you want this iframe: src="http://www.example.com/mypage.php"
Well, instead of HTML to specify the iframe, use a javascript to build the HTML for your iframe, get the parent url through javascript "at build time", and send it as a url GET parameter in the querystring of your src target, like so:
<script type="text/javascript">
url = parent.document.URL;
document.write('<iframe src="http://example.com/mydata/page.php?url=' + url + '"></iframe>');
</script>
Then, find yourself a javascript url parsing function that parses the url string to get the url variable you are after, in this case it's "url".
I found a great url string parser here:
http://www.netlobo.com/url_query_string_javascript.html

If your iframe is from another domain, (cross domain), you will simply need to use this:
var currentUrl = document.referrer;
and - here you've got the main url!

The following line will work: document.location.ancestorOrigins[0] this one returns the ancestor domain name.

You're correct. Subdomains are still considered separate domains when using iframes. It's possible to pass messages using postMessage(...), but other JS APIs are intentionally made inaccessible.
It's also still possible to get the URL depending on the context. See other answers for more details.

For pages on the same domain and different subdomain, you can set the document.domain property via javascript.
Both the parent frame and the iframe need to set their document.domain to something that is common betweeen them.
i.e.
www.foo.mydomain.com and api.foo.mydomain.com could each use either foo.mydomain.com or just mydomain.com and be compatible (no, you can't set them both to com, for security reasons...)
also, note that document.domain is a one way street. Consider running the following three statements in order:
// assume we're starting at www.foo.mydomain.com
document.domain = "foo.mydomain.com" // works
document.domain = "mydomain.com" // works
document.domain = "foo.mydomain.com" // throws a security exception
Modern browsers can also use window.postMessage to talk across origins, but it won't work in IE6.
https://developer.mozilla.org/en/DOM/window.postMessage

Try it:
document.referrer
When you change you are in a iframe your host is "referrer".

There's a lot a answers to this question, and none of them are definitely the best in terms of support or reliability.
Options
window.location.ancestorOrigins[0] will get the parent url, but this api only works in chromium browsers (see support). this also supports nested iframes, where the bottom most child has access to the urls of each parent iframe.
document.referrer is the most common answer but is not always reliable
navigation inside of the iframe would show the last page instead of the parent frame url
redirects only show the most recent referrer to the current page
if the page reloads itself the referer becomes the page itself
http child with an https parent has an empty string for referrer
Things that don't work
window.parent.location.href. If the parent and the child are in different domains, this api is blocked by modern browsers (see here), and will throw an error.
Recommendation
If supported, I prefer window.location.ancestorOrigins[0]. document.referrer can work, but is less reliable, making it my fallback option. If you do use document referrer, try to call it on the first framed page load, before navigation or redirects, to get the parent address.

there is a cross browser script for get parent origin:
private getParentOrigin() {
const locationAreDisctint = (window.location !== window.parent.location);
const parentOrigin = ((locationAreDisctint ? document.referrer : document.location) || "").toString();
if (parentOrigin) {
return new URL(parentOrigin).origin;
}
const currentLocation = document.location;
if (currentLocation.ancestorOrigins && currentLocation.ancestorOrigins.length) {
return currentLocation.ancestorOrigins[0];
}
return "";
}
This code, should work on Chrome and Firefox.

var url = (window.location != window.parent.location) ? document.referrer: document.location;
I found that the above example suggested previously worked when the script was being executed in an iframe however it did not
retrieve the url when the script was executed outside of an iframe,
a slight adjustment was required:
var url = (window.location != window.parent.location) ? document.referrer: document.location.href;

I've had issues with this. If using a language like php when your page first loads in the iframe grab $_SERVER['HTTP_REFFERER'] and set it to a session variable.
This way when the page loads in the iframe you know the full parent url and query string of the page that loaded it. With cross browser security it's a bit of a headache counting on window.parent anything if you you different domains.

I've found in the cases where $_SERVER['HTTP_REFERER'] doesn't work (I'm looking at you, Safari), $_SERVER['REDIRECT_SCRIPT_URI'] has been a useful backup.

Assuming you get to tell the parent page how to set up the iframe, to easily but insecurily get the full URL with a path and URL parameters, include referrerpolicy="unsafe-url" when specifying the iframe:
<iframe src="https://example.com/innersite" referrerpolicy="unsafe-url" title="My Title"></iframe>
Then you can get the full original URL with:
document.referrer
Many of the other answers only work when the iframe src is the same as the parent's domain.
Fallbacks:
In case there are security issues, you could do a fallback like https://stackoverflow.com/a/5697801/1226799 says where the parent explicitly sends its URL in a URL parameter for the iframe URL, but an attacker could easily fake that.
I believe you could also use message passing and check the origin of the event: https://stackoverflow.com/a/61548595/1226799

I couldnt get previous solution to work but I found out that if I set the iframe scr with for example http:otherdomain.com/page.htm?from=thisdomain.com/thisfolder then I could, in the iframe extract thisdomain.com/thisfolder by using following javascript:
var myString = document.location.toString();
var mySplitResult = myString.split("=");
fromString = mySplitResult[1];

The problem with the PHP $_SERVER['HTTP_REFFERER'] is that it gives the fully qualified page url of the page that brought you to the parent page. That's not the same as the parent page, itself. Worse, sometimes there is no http_referer, because the person typed in the url of the parent page. So, if I get to your parent page from yahoo.com, then yahoo.com becomes the http_referer, not your page.

In chrome it is possible to use location.ancestorOrigins
It will return all parent urls

This worked for me to access the iframe src url.
window.document.URL

I know his is super old but it blows my mind no one recommended just passing cookies from one domain to the other. As you are using subdomains you can share cookies from a base domain to all subdomains just by setting cookies to the url .basedomain.com
Then you can share whatever data you need through the cookies.

Get All Parent Iframe functions and HTML
var parent = $(window.frameElement).parent();
//alert(parent+"TESTING");
var parentElement=window.frameElement.parentElement.parentElement.parentElement.parentElement;
var Ifram=parentElement.children;
var GetUframClass=Ifram[9].ownerDocument.activeElement.className;
var Decision_URLLl=parentElement.ownerDocument.activeElement.contentDocument.URL;

Related

Establish parent origin for postMessage communication

I have an iframe that is embedded into 3rd party sites and I want those sites to be able to communicate with said iframe through postMessage. I'd like to limit the origin that can communicate with the iframe to the originating (instantiating) webpage's origin. I currently achieve this by just appending the origin to the iframe as such:
<iframe src = "https://whatever.com/iframe?host=${window.location.href}" />
However, I'd like to move away from this method for reasons that are out of scope for this question. As such, I was considering verifying the message through a combination of window.parent and ducument.referrer. Something like:
const originatingOrigin = parse(document.referrer).origin;
document.addEventListener("message", function (message)
{
if (message.origin !== originatingOrigin || window.parent !== message.source)
return;
});
Is this 1) as secure as when I was passing the URL in myself and 2) foolproof in that there are no cases when document.referrer is blocked let's say, in which case the API would be broken.
So, the range of concerns are:
Can document.referrer ever be null/unavailable/incorrect in this setup. I know its possible to be different if you for example go through a redirect, but given that my script will be creating the iframe and setting the src that case shouldn't be a concern.
Given that I parse/store the document.referrer, are there any weird tricks other adversarial iframes could communicate/move the iframe (to confused the window.parent, etc).
It would appear that setting Referrer-Policy: no-referrer makes document.referrer not work.

Dynamically set document.domain to iframe

I have an iframe that injects in pages, called him "helper". So due to same origin policy I need to set iframe domain the same is parent window domain. But I can't get access to parent window domain. How can it be solved?
This code is currently working for 2nd level domains:
pathArray = window.location.host.split('.');
var arrLength = pathArray.length;
var domainName = pathArray.slice(arrLength - 2, arrLength).join('.');
document.domain = domainName;
but I need to somehow get it from parent window rather than relying on 2nd level domain
I do not know if it will help but i use this in iframe
try {
var domainName = window.parent.parent.iframeData.domainName;
}
//Access violation
catch (err) {
document.domain = window.location.hostname.replace('www.', '');
}
So i check if domain already set we have exception ang try to guess domain, in either case, there is no need to set a domain
EDIT:
More correctly to use post message to set domain if needed
In short, it can't. Setting document.domain only works when the iFrame and containing window are actually part of the same domain. If a browser were to let you set document.domain to something other than the domain you were actually on, it would be a security violation. Consider, any malicious script could just say 'No really, trust me on this one' and the browser would essentially be saying, 'Oh, okay, since you asked so nicely, here's all the permission you want'.
document.domain can only be set to a parent domain of the actual domain of the page. If an iFrame and a containing window don't share at least that, then no browser will allow them to cross talk.
Unless I've misunderstood your question. Feel free to post some examples to clarify.
Assuming you parent can be a.domain.com
and your iframe is b.domain.com - then you can do what your are attempting.
If you MUST know what the parent is, pass it in the iframe src attribute or try document.referrer
add document.domain = 'your.domain' in both the pages.
like this. don't forget both parent.top
document.domain = 'corp.local'; only parent like
document.domain = 'corp'; won't work.
As I've mentioned here. javascript get iframe url's current page on subdomain
this document helped. http://javascript.info/tutorial/same-origin-security-policy

Chrome iframe's location.href is undefined

I'm working over the same domain giving the ability for a user to navigate within the iframe on the page. I'd like to handle the onload of the iframe in Chrome and to process the actual href the user navigated to. When I'm trying to access
document.getElementById("contentFrame").contentWindow.location.href
it says undefined. Debugger tells that location is an object, but I cannot figure out what property to use.
any guess?
Chrome v15
If you really are on the same domain, use the same protocol and port it should work. Here's an example: http://jsfiddle.net/csVcL/1/
Maybe you're on different subdomains, in which case you need to use document.domain
If you are not in the same domain, you are not allowed to access the href or any other properties on the remote window.

Debugging "unsafe javascript attempt to access frame with URL ... "

So, the error message is the security restriction to access a parent frame or window from within an (i)frame from a different domain.
(Unsafe javascript attempt to access frame with URL xxx from frame with URL yyy. Domains, protocols, and ports must match).
However, there is no line shown in webkit or chrome from where this error is generated.
So how do I get a list of the lines that infringe upon this? I know I can just search, but does this apply to cookies as well (document.cookie, etc) ? Is there a list of things that are disallowed?
Edit: Also, what do I need to use instead of $(window.top)?
Thanks.
If you own all of the pages (the containing document and the iframe document) just stick some javascript in each of them to allow them to communicate happily:
document.domain = 'myDomain.com';
Any call from inside the frame to window instead of window.frames[my frame] will cause a violation unless you have the document.domain set to match the parent. https://developer.mozilla.org/en/DOM/document.domain

Access parent URL from iframe

Okay, I have a page on and on this page I have an iframe. What I need to do is on the iframe page, find out what the URL of the main page is.
I have searched around and I know that this is not possible if my iframe page is on a different domain, as that is cross-site scripting. But everywhere I've read says that if the iframe page is on the same domain as the parent page, it should work if I do for instance:
parent.document.location
parent.window.document.location
parent.window.location
parent.document.location.href
... or other similar combos, as there seems to be multiple ways to get the same info.
Anyways, so here's the problem. My iframe is on the same domain as the main page, but it is not on the same SUB domain. So for instance I have
http:// www.mysite.com/pageA.html
and then my iframe URL is
http:// qa-www.mysite.com/pageB.html
When I try to grab the URL from pageB.html (the iframe page), I keep getting the same access denied error. So it appears that even sub-domains count as cross-site scripting, is that correct, or am I doing something wrong?
Yes, accessing parent page's URL is not allowed if the iframe and the main page are not in the same (sub)domain. However, if you just need the URL of the main page (i.e. the browser URL), you can try this:
var url = (window.location != window.parent.location)
? document.referrer
: document.location.href;
Note:
window.parent.location is allowed; it avoids the security error in the OP, which is caused by accessing the href property: window.parent.location.href causes "Blocked a frame with origin..."
document.referrer refers to "the URI of the page that linked to this page." This may not return the containing document if some other source is what determined the iframe location, for example:
Container iframe # Domain 1
Sends child iframe to Domain 2
But in the child iframe... Domain 2 redirects to Domain 3 (i.e. for authentication, maybe SAML), and then Domain 3 directs back to Domain 2 (i.e. via form submission(), a standard SAML technique)
For the child iframe the document.referrer will be Domain 3, not the containing Domain 1
document.location refers to "a Location object, which contains information about the URL of the document"; presumably the current document, that is, the iframe currently open. When window.location === window.parent.location, then the iframe's href is the same as the containing parent's href.
I just discovered a workaround for this problem that is so simple, and yet I haven't found any discussions anywhere that mention it. It does require control of the parent frame.
In your iFrame, say you want this iframe: src="http://www.example.com/mypage.php"
Well, instead of HTML to specify the iframe, use a javascript to build the HTML for your iframe, get the parent url through javascript "at build time", and send it as a url GET parameter in the querystring of your src target, like so:
<script type="text/javascript">
url = parent.document.URL;
document.write('<iframe src="http://example.com/mydata/page.php?url=' + url + '"></iframe>');
</script>
Then, find yourself a javascript url parsing function that parses the url string to get the url variable you are after, in this case it's "url".
I found a great url string parser here:
http://www.netlobo.com/url_query_string_javascript.html
If your iframe is from another domain, (cross domain), you will simply need to use this:
var currentUrl = document.referrer;
and - here you've got the main url!
The following line will work: document.location.ancestorOrigins[0] this one returns the ancestor domain name.
You're correct. Subdomains are still considered separate domains when using iframes. It's possible to pass messages using postMessage(...), but other JS APIs are intentionally made inaccessible.
It's also still possible to get the URL depending on the context. See other answers for more details.
For pages on the same domain and different subdomain, you can set the document.domain property via javascript.
Both the parent frame and the iframe need to set their document.domain to something that is common betweeen them.
i.e.
www.foo.mydomain.com and api.foo.mydomain.com could each use either foo.mydomain.com or just mydomain.com and be compatible (no, you can't set them both to com, for security reasons...)
also, note that document.domain is a one way street. Consider running the following three statements in order:
// assume we're starting at www.foo.mydomain.com
document.domain = "foo.mydomain.com" // works
document.domain = "mydomain.com" // works
document.domain = "foo.mydomain.com" // throws a security exception
Modern browsers can also use window.postMessage to talk across origins, but it won't work in IE6.
https://developer.mozilla.org/en/DOM/window.postMessage
Try it:
document.referrer
When you change you are in a iframe your host is "referrer".
There's a lot a answers to this question, and none of them are definitely the best in terms of support or reliability.
Options
window.location.ancestorOrigins[0] will get the parent url, but this api only works in chromium browsers (see support). this also supports nested iframes, where the bottom most child has access to the urls of each parent iframe.
document.referrer is the most common answer but is not always reliable
navigation inside of the iframe would show the last page instead of the parent frame url
redirects only show the most recent referrer to the current page
if the page reloads itself the referer becomes the page itself
http child with an https parent has an empty string for referrer
Things that don't work
window.parent.location.href. If the parent and the child are in different domains, this api is blocked by modern browsers (see here), and will throw an error.
Recommendation
If supported, I prefer window.location.ancestorOrigins[0]. document.referrer can work, but is less reliable, making it my fallback option. If you do use document referrer, try to call it on the first framed page load, before navigation or redirects, to get the parent address.
there is a cross browser script for get parent origin:
private getParentOrigin() {
const locationAreDisctint = (window.location !== window.parent.location);
const parentOrigin = ((locationAreDisctint ? document.referrer : document.location) || "").toString();
if (parentOrigin) {
return new URL(parentOrigin).origin;
}
const currentLocation = document.location;
if (currentLocation.ancestorOrigins && currentLocation.ancestorOrigins.length) {
return currentLocation.ancestorOrigins[0];
}
return "";
}
This code, should work on Chrome and Firefox.
var url = (window.location != window.parent.location) ? document.referrer: document.location;
I found that the above example suggested previously worked when the script was being executed in an iframe however it did not
retrieve the url when the script was executed outside of an iframe,
a slight adjustment was required:
var url = (window.location != window.parent.location) ? document.referrer: document.location.href;
I've had issues with this. If using a language like php when your page first loads in the iframe grab $_SERVER['HTTP_REFFERER'] and set it to a session variable.
This way when the page loads in the iframe you know the full parent url and query string of the page that loaded it. With cross browser security it's a bit of a headache counting on window.parent anything if you you different domains.
I've found in the cases where $_SERVER['HTTP_REFERER'] doesn't work (I'm looking at you, Safari), $_SERVER['REDIRECT_SCRIPT_URI'] has been a useful backup.
Assuming you get to tell the parent page how to set up the iframe, to easily but insecurily get the full URL with a path and URL parameters, include referrerpolicy="unsafe-url" when specifying the iframe:
<iframe src="https://example.com/innersite" referrerpolicy="unsafe-url" title="My Title"></iframe>
Then you can get the full original URL with:
document.referrer
Many of the other answers only work when the iframe src is the same as the parent's domain.
Fallbacks:
In case there are security issues, you could do a fallback like https://stackoverflow.com/a/5697801/1226799 says where the parent explicitly sends its URL in a URL parameter for the iframe URL, but an attacker could easily fake that.
I believe you could also use message passing and check the origin of the event: https://stackoverflow.com/a/61548595/1226799
I couldnt get previous solution to work but I found out that if I set the iframe scr with for example http:otherdomain.com/page.htm?from=thisdomain.com/thisfolder then I could, in the iframe extract thisdomain.com/thisfolder by using following javascript:
var myString = document.location.toString();
var mySplitResult = myString.split("=");
fromString = mySplitResult[1];
The problem with the PHP $_SERVER['HTTP_REFFERER'] is that it gives the fully qualified page url of the page that brought you to the parent page. That's not the same as the parent page, itself. Worse, sometimes there is no http_referer, because the person typed in the url of the parent page. So, if I get to your parent page from yahoo.com, then yahoo.com becomes the http_referer, not your page.
In chrome it is possible to use location.ancestorOrigins
It will return all parent urls
This worked for me to access the iframe src url.
window.document.URL
I know his is super old but it blows my mind no one recommended just passing cookies from one domain to the other. As you are using subdomains you can share cookies from a base domain to all subdomains just by setting cookies to the url .basedomain.com
Then you can share whatever data you need through the cookies.
Get All Parent Iframe functions and HTML
var parent = $(window.frameElement).parent();
//alert(parent+"TESTING");
var parentElement=window.frameElement.parentElement.parentElement.parentElement.parentElement;
var Ifram=parentElement.children;
var GetUframClass=Ifram[9].ownerDocument.activeElement.className;
var Decision_URLLl=parentElement.ownerDocument.activeElement.contentDocument.URL;

Categories

Resources