Unsafe JavaScript Attempt when trying to reload frame - javascript

This is annoying. I am trying to make it so that when the I press F5, the frame reloads. I have got it so that if the focus is on the main page (not the iframe) it works. However, when I try to implement a similar solution or even make any attempt to communicate with the iframe, I get an 'Unsafe JavaScript attempt to access frame'. To be more specific, the exact error is:
Unsafe JavaScript attempt to access frame with URL http://www.spow.tk/projects/test from frame with URL http://spow.tk/projects/Explorer/02/. Domains, protocols and ports must match.
Please help as this really is a pain.
Thanks

Those two sites are on different domains. Due to security restrictions in Javascript, you cannot script across domains. Check out Wikipedia or Mozilla for more info (quoted Mozilla to prevent link rot):
The same origin policy prevents a document or script loaded from one origin from getting or setting properties of a document from another origin. This policy dates all the way back to Netscape Navigator 2.0.
Mozilla considers two pages to have the same origin if the protocol, port (if one is specified), and host are the same for both pages. The following table gives examples of origin comparisons to the URL http://store.company.com/dir/page.html:
URL Outcome Reason
http://store.company.com/dir2/other.html Success
http://store.company.com/dir/inner/another.html Success
https://store.company.com/secure.html Failure Different protocol
http://store.company.com:81/dir/etc.html Failure Different port
http://news.company.com/dir/other.html Failure Different host
There is one exception to the same origin rule. A script can set the value of document.domain to a suffix of the current domain. If it does so, the shorter domain is used for subsequent origin checks. For example, assume a script in the document at http://store.company.com/dir/other.html executes the following statement:
document.domain = "company.com";
After that statement executes, the page would pass the origin check with http://company.com/dir/page.html. However, by the same reasoning, company.com could not set document.domain to othercompany.com.
Port number is kept by the browser separately. Any call to the setter, including document.domain = document.domain causes the port number to be overwritten with null. Therefore one can not make company.com:8080 talk to company.com by only setting document.domain = "company.com" in the first. It has to be set in both so that port numbers are both null.

spow.tk and www.spow.tk are considered to be different domains.
One thing you can do however, is to force your site to use one or the other, so that this issue doesn't arise again. For instance, if you're using Apache, you can modify your .htaccess to redirect all requests from spow.tk to www.spow.tk (or www.spow.tk to spow.tk if that's what you prefer). Even if your users or code reference one domain, the request will be redirect to the domain you specified.

Related

JavaScript document.domain Uncaught DOMException: Blocked a frame with origin

While I was testing the SOP, i came to this scenario two documents has a relationship with the same domain as i would expected and it throws an error when i try to get the location.
To reproduce the problem:
Open https://www.google.com
from the console let opened = window.open("https://www.google.com")
from the same window do opened.location.toString() which will return the correct location
from the second tab's console do document.domain = "www.google.com"
from the first tab do opened.location.toString() and you will get an error
Uncaught DOMException: Blocked a frame with origin "https://www.google.com" from accessing a cross-origin frame.
at <anonymous>:1:12
Can anyone explain this strange behavior?
This error is not a bug. The same-origin policy is a security mechanism that ensures that window objects only have access to the informations they are authorized to get. In your case, this includes having access to opened.location.
Upon creation, both tabs have the same origin, which allows the first one to access opened.location. But after the call to document.domain='www.google.com', they don't anymore.
"What? But in both tabs, window.location.origin are identical"
Yes, but it is a little bit more complex. The origin is defined by the scheme/host/port tuple, see #TheUnknown's answer for more details. The scheme and host stay the same all along, and they're the one included in the string of window.location.origin.
The tricky thing to know is that any call to document.domain, including document.domain = document.domain, causes the port number to be overwritten with null, therefore causing a difference in the two tabs' origins, and preventing them from communicating informations like opened.location with one another, thus the error.
Informations extracted from MDN's guide on same-origin policy
First, I would recommend, you read Same-origin Policy.
The same-origin policy is a critical security mechanism that restricts
how a document or script loaded from one origin can interact with a
resource from another origin. It helps isolate potentially malicious
documents, reducing possible attack vectors.
Two URLs have the same origin if the protocol, port (if specified), and host are the same for both. You may see this referenced as the "scheme/host/port tuple", or just "tuple". (A "tuple" is a set of items that together comprise a whole — a generic form for double/triple/quadruple/quintuple/etc.)
In this particular case, you open a window with HTTPS protocol, however when you set the domain, the protocol is changed to HTTP, see image below:
As per 1, if the protocols are not the same, then its a violation of the principle and hence you get the error
Uncaught DOMException: Blocked a frame with origin
"https://www.google.com" from accessing a cross-origin frame.
cross-origin is the keyword here.
Also, check out this SecurityError: Blocked a frame with origin from accessing a cross-origin frame for more details.
This will be a bit uninformative (just states facts), nevertheless:
After you change domain in window B, window B stops accounting window A as opener.
Since window A is no longer considered an opener of window B, the access is prohibited.
This makes me think, that altering document.domain is considered potentially insecure and is "punished" by orphaning the child window.

Allowing cross-site requests between subdomains without changing file contents of second sub domain

I am currently attempting to wrap a web application (ConnectWise) for inclusion within my company's central intranet site. It's a fairly simple process for the most part; create a containing page, with an iframe, point the iframe at the ConnectWise url. This part works for almost all of the functionality.
The problem comes during certain select features of the app (in this case, part of the process of creating a timesheet entry), which simply fail to work. Chrome gives the following console output.
Uncaught SecurityError: Failed to read the 'frame' property from 'Window': Blocked a frame with origin "https://app.example.com" from accessing a frame with origin "https://host.example.com". Protocols, domains, and ports must match.
I am aware this is caused by the security options for cross-site and same-origin policies. Given the following points, is there a way to overcome this?
I have full control over https://host.example.com
I can change html, javascript, and file contents
I can change IIS settings and headers
I have partial control over https://app.example.com
I can not change html, javascript, and file contents
I can change IIS settings and headers.
I have tried setting the Access-Control-Allow-Origin on each server, which so far is the only method I've come across that does not involve being able to change the file contents for the app server. This does not appear to work when given the settings (and combinations of settings) of
* or https://app.example.com while on https://host.example.com
* or https://host.example.com while on https://app.example.com
Edit:
The solution to this "duplicate" question is not applicable here. I do not have access to change file contents (including javascript) of the iframed page (app.example.com). Additionally, the script requiring the permission to run is the page within the iframe, not the page hosting the iframe.
CORS headers such as Access-Control-Allow-Origin only affect AJAX requests, not DOM access.
However, If they are both on the same domain but different subdomains then you can include the following on each page:
document.domain = 'example.com';
From MDN:
One document is allowed to access another if they have both set
document.domain to the same value, indicating their intent to
cooperate
If app.example.com has any script includes to host.example.com then you could put the above code in those scripts to set the domain.
e.g.
<script src="https://host.example.com/setup.js"></script>
No, it is not possible.
Access-Control-Allow-Origin primarily affects getting raw data from HTTP requests, not live DOMs.
postMessage can let frames on different origins communicate, but it requires JS to be included on both pages.

error : Permission denied to access property 'document'

How can I fix this message in Firefox? I am using an Iframe which has an anchor tag? I would like to get a reference to this anchor but i am getting this error when I am trying to access anchor:
var frameWindow = document.getElementById('myIframe').contentWindow;
var anchor = frameWindow.document.links[0]; //.getElementsByClassName('a');
anchor.onclick....
Relaxing the same-origin policy
In some circumstances the same-origin policy is too restrictive, posing problems for large websites that use multiple subdomains. Here are four techniques for relaxing it:
document.domain property
If two windows (or frames) contain scripts that set domain to the same value, the same-origin policy is relaxed for these two windows, and each window can interact with the other. For example, cooperating scripts in documents loaded from orders.example.com and catalog.example.com might set their document.domain properties to “example.com”, thereby making the documents appear to have the same origin and enabling each document to read properties of the other. This might not always work as the port stored in the internal representation can become marked as null. In other words example.com port 80 will become example.com port null because we update document.domain. Port null might not be treated as 80 ( depending on your browser ) and hence might fail or succeed depending on your browser.
Cross-Origin Resource Sharing
The second technique for relaxing the same-origin policy is being standardized under the name Cross-Origin Resource Sharing. This draft standard extends HTTP with a new Origin request header and a new Access-Control-Allow-Origin response header. It allows servers to use a header to explicitly list origins that may request a file or to use a wildcard and allow a file to be requested by any site. Browsers such as Firefox 3.5 and Safari 4 use this new header to allow the cross-origin HTTP requests with XMLHttpRequest that would otherwise have been forbidden by the same-origin policy.[7]
Cross-document messaging
Another new technique, cross-document messaging allows a script from one page to pass textual messages to a script on another page regardless of the script origins. Calling the postMessage() method on a Window object asynchronously fires an "onmessage" event in that window, triggering any user-defined event handlers. A script in one page still cannot directly access methods or variables in the other page, but they can communicate safely through this message-passing technique.
JSONP
JSONP allows a page to receive JSON data from a different domain by adding a <script> element to the page which loads a JSON response from a different domain.
The function call is the "P" of JSONP—the "padding" around the pure JSON, or according to some the "prefix". By convention, the browser provides the name of the callback function as a named query parameter value, typically using the name jsonp or callback as the named query parameter field name, in its request to the server, e.g.,
<script type="application/javascript"
src="http://server2.example.com/Users/1234?jsonp=parseResponse">
</script>
In this example, the received payload would be:
parseResponse({"Name": "Foo", "Id": 1234, "Rank": 7});
If the iframe points to a different domain, you will get this error. This is an example of your browser preventing cross-site scripting: http://en.wikipedia.org/wiki/Cross-site_scripting
The error is due to the same-origin policy like explained in other answers. I post this answer as a workaround to execute JavaScript code in a web console.
My comment suggesting to use Firebug CD command no longer works because Firebug is not supported anymore.
But there is a similar feature in Firefox Developer Tools, you can switch the domain name by selecting the iframe context picker button like described here: https://developer.mozilla.org/en-US/docs/Tools/Working_with_iframes

How can I access a parent DOM from an iframe on a different domain?

I have a website and my domain is registered through Network Solutions (who I would not recommend). I'm using their Web Forwarding feature which allows me to "mask" my domain so that when a user visits http://lucasmccoy.com they are actually seeing http://lucasmccoy.comlu.com/ through an HTML frame. The advantages of this are that the address bar still shows http://lucasmccoy.com/.
The disadvantages are that I cannot directly edit the HTML page in which the frame is owned. For example, I cannot change the page title or favicon. I have tried doing it like so:
$(function() {
parent.document.title = 'Lucas McCoy';
});
But of course this gives me a JavaScript error:
Unsafe JavaScript attempt to access frame with URL http://lucasmccoy.com/ from frame with URL http://lucasmccoy.comlu.com/. Domains, protocols and ports must match.
I looked at this question attempting to do the same thing except the OP has access to the other pages HTML whereas I do not.
Is there anyway in JavaScript/jQuery to make a cross-domain request to the DOM when you don't have access to that domain? Or is this something browsers just will not let happen for security reasons.
No. Most browsers implement the same origin policy.

"Access is denied" error on accessing iframe document object

For posting AJAX forms in a form with many parameters, I am using a solution of creating an iframe, posting the form to it by POST, and then accessing the iframe's content.
specifically, I am accessing the content like this:
$("some_iframe_id").get(0).contentWindow.document
I tested it and it worked.
On some of the pages, I started getting an "Access is denied" error. As far as I know, this shouldn't happen if the iframe is served from the same domain.
I'm pretty sure it was working before. Anybody have a clue?
If I'm not being clear enough: I'm posting to the same domain. So this is not a cross-domain request. I am testing on IE only.
P.S. I can't use simple ajax POST queries (don't ask...)
Solved it by myself!
The problem was, that even though the correct response was being sent (verified with Fiddler), it was being sent with an HTTP 500 error code (instead of 200).
So it turns out, that if a response is sent with an error code, IE replaces the content of the iframe with an error message loaded from the disk (res://ieframe.dll/http_500.htm), and that causes the cross-domain access denied error.
Beware of security limitations associated to iFrames, like Cross domain restriction (aka CORS). Below are 3 common errors related to CORS :
Load an iFrame with a different domain. (Ex: opening "www.foo.com" while top frame is "www.ooof.com")
Load an iFrame with a different port: iFrame's URL port differs from the one of the top frame.
Different protocols : loading iFrame resource via HTTPS while parent Frame uses HTTP.
My issue was the X-Frame-Options HTTP header. My Apache configuration has it set to:
Header always append X-Frame-Options DENY
Removing it allowed it to work. Specifically in my case I was using iframe transport for jQuery with the jQuery file upload plugin to upload files in IE 9 and IE 10.
I know this question is super-old, but I wanted to mention that the above answer worked for me: setting the document.domain to be the same on each of the pages-- the parent page and the iframe page. However in my search, I did find this interesting article:
http://softwareas.com/cross-domain-communication-with-iframes
Note if you have a iframe with src='javascript:void(0)' then javascript like frame.document.location =... will fail with Access Denied error in IE. Was using a javascript library that interacts with a target frame. Even though the location it was trying to change the frame to was on the same domain as parent, the iframe was initially set to javascript:void which triggered the cross domain access denied error.
To solve this I created a blank.html page in my site and if I need to declare an iframe in advance that will initially be blank until changed via javascript, then I point it to the blank page so that src='/content/blank.html' is in the same domain.
Alternatively you could create the iframe completely through javascript so that you can set the src when it is created, but in my case I was using a library which reqired an iframe already be declared on the page.
Basically, this error occurs when the document in frame and outside of ii have different domains. So to prevent cross-side scripting browsers disable such execution.
if it is a domain issue (or subdomain) such as www.foo.com sending a request to www.api.foo.com
on each page you can set the
document.domain = www.foo.com
to allow for "cross-domain" permissions

Categories

Resources