I'm trying to add some pages from my site www.drewgl.com to stumbleupon. It is very dependent on javascript. When I view my site through stumbleupon the javascript gets blocked. Specifically, I see the error:
Uncaught SecurityError: Blocked a frame with origin
"http://www.drewgl.com" from accessing a frame with origin
"http://www.stumbleupon.com". Protocols, domains, and ports must match
I'm using rails 4 deployed to heroku. I have my X-frame options set to allow all. I read through the answers here:
SecurityError: Blocked a frame with origin from accessing a cross-origin frame
and it seems as if the only way to get around this issue is to use window.postmessage to send messages between the two pages. To do this, however, you must own both pages.
Of course, this condition cannot be met with Stumbleupon, so how can I get around the issue?
Edit: I just downloaded the stumbleupon toolbar for chrome. After doing this, I no longer get the above error message. Either way I'd still like to fix this problem for stumblers that don't have the toolbar.
Rails app not loading on StumbleUpon? Add this to your ApplicationController
before_action :allow_iframe_requests
private
def allow_iframe_requests
response.headers.delete('X-Frame-Options')
end
https://github.com/rails/rails/issues/6311
Figured it out. If anyone's curious, you're not allowed to access the current path from within an iframe. This chunk of code was causing the issue:
// if (top.location.pathname === '/users/sign_in')
// {
// $('#login').modal('show');
// }
Related
I'm getting this warning in Chrome when I try to show a dialog (alert()/confirm()/prompt()) from an iframe. Both domains belong to me.
A different origin subframe tried to create a JavaScript dialog. This is no longer allowed and was blocked. See https://www.chromestatus.com/feature/5148698084376576 for more details.
Could I resolve this via .htaccess or with an HTTP header or anything like that?
Use top.alert(), top.confirm(), & top.prompt() instead, which, if you have your CORS set up, will use the parent window's (if there is one) dialogs which are not blocked by this Chrome update.
This question already has answers here:
SecurityError: Blocked a frame with origin from accessing a cross-origin frame
(9 answers)
Closed 1 year ago.
My website provides functionality for embedding a video from my website via an iframe (similar to Youtube or any other video portals).
However, is there a way to exactly detect, which website included mine as an iframe.
Tried within my iframe embed, trying to detect parent's URL
if (window !== window.top) {
console.log(window.top.location.href);
console.log(window.parent.location.href);
}
but ended up with an error
Uncaught DOMException: Blocked a frame with origin "https://myurl.com" from accessing a cross-origin frame.
at console.log (<anonymous>)
at https://www.myurl.com/embed/1544401:20:21
Is there a workaround?
UPD. Solved by using document.referrer
You can't access an <iframe> with different origin using JavaScript, it would be a huge security flaw if you could do it. For the same-origin policy browsers block scripts trying to access a frame with a different origin.
you can work around this problem using window.postMessage and its relative message event to send messages between the two pages, like this:
//in your main page
const frame = document.getElementById('your-frame-id');
frame.contentWindow.postMessage(/*any variable or object here*/, 'http://your-second-site.com');
//In your <iframe> (contained in the main page):
window.addEventListener('message', event => {
// IMPORTANT: check the origin of the data!
if (event.origin.startsWith('http://your-first-site.com')) {
// The data was sent from your site.
// Data sent with postMessage is stored in event.data:
console.log(event.data);
} else {
// The data was NOT sent from your site!
// Be careful! Do not use it. This else branch is
// here just for clarity, you usually shouldn't need it.
return;
}
});
This method can be applied in both directions, creating a listener in the main page too, and receiving responses from the frame. The same logic can also be implemented in pop-ups and basically any new window generated by the main page (e.g. using window.open()) as well, without any difference.
or just disable the same origin policy in your browser
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.
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.
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