Ошибка uncaught securityerror blocked a frame with origin

Same-origin policy

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.

Origin is considered different if at least one of the following parts of the address isn’t maintained:

protocol://hostname:port/...

Protocol, hostname and port must be the same of your domain if you want to access a frame.

NOTE: Internet Explorer is known to not strictly follow this rule, see here for details.

Examples

Here’s what would happen trying to access the following URLs from http://www.example.com/home/index.html

URL                                             RESULT
http://www.example.com/home/other.html       -> Success
http://www.example.com/dir/inner/another.php -> Success
http://www.example.com:80                    -> Success (default port for HTTP)
http://www.example.com:2251                  -> Failure: different port
http://data.example.com/dir/other.html       -> Failure: different hostname
https://www.example.com/home/index.html:80   -> Failure: different protocol
ftp://www.example.com:21                     -> Failure: different protocol & port
https://google.com/search?q=james+bond       -> Failure: different protocol, port & hostname

Workaround

Even though same-origin policy blocks scripts from accessing the content of sites with a different origin, if you own both the pages, 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*/, 'https://your-second-site.example');
    

    The second argument to postMessage() can be '*' to indicate no preference about the origin of the destination. A target origin should always be provided when possible, to avoid disclosing the data you send to any other site.

  • In your <iframe> (contained in the main page):

    window.addEventListener('message', event => {
        // IMPORTANT: check the origin of the data!
        if (event.origin === 'https://your-first-site.example') {
            // 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.

Disabling same-origin policy in your browser

There already are some good answers about this topic (I just found them googling), so, for the browsers where this is possible, I’ll link the relative answer. However, please remember that disabling the same-origin policy will only affect your browser. Also, running a browser with same-origin security settings disabled grants any website access to cross-origin resources, so it’s very unsafe and should NEVER be done if you do not know exactly what you are doing (e.g. development purposes).

  • Google Chrome
  • Mozilla Firefox
  • Safari
  • Opera: same as Chrome
  • Microsoft Edge: same as Chrome
  • Brave: same as Chrome
  • Microsoft Edge (old non-Chromium version): not possible
  • Microsoft Internet Explorer
Published: 05 Dec 2019
Last Modified Date: 24 Aug 2022

Issue

When saving a Custom View in an Embedded View, the following error occurred and the view cannot be saved.
 

«An unexpected error occurred. If you continue to receive this error, please contact your Tableau Server Administrator. 
Uncaught SecurityError: Blocked a frame with origin «http://<Tableau Server>» from accessing a cross-origin frame.»

Environment

  • Tableau Server 2019.4.0
  • Tableau Cloud
  • Custom views

Resolution

For Tableau Server, upgrade to 2020.1 or later. Or,
as a workaround, save the custom view on Tableau Server or Tableau Cloud directly, and not in an embedded view.

Cause

This is a known issue which is fixed in more recent version of Tableau Server and Tableau Cloud.




Answer by Vincenzo Poole

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.,I am loading an <iframe> in my HTML page and trying to access the elements within it using Javascript, but when I try to execute my code, I get the following error:,Even though same-origin policy blocks scripts from accessing the content of sites with a different origin, if you own both the pages, you can work around this problem using window.postMessage and its relative message event to send messages between the two pages, like this:,

4

@SabaAhang just check for the iframe.src, and if the site it’s different from your domain’s hostname then you can’t access that frame.

– Marco Bonelli

Oct 17 ’15 at 9:34

Origin is considered different if at least one of the following parts of the address isn’t maintained:

protocol://hostname:port/...

Here’s what would happen trying to access the following URLs from http://www.example.com/home/index.html

URL                                             RESULT 
http://www.example.com/home/other.html       -> Success 
http://www.example.com/dir/inner/another.php -> Success 
http://www.example.com:80                    -> Success (default port for HTTP) 
http://www.example.com:2251                  -> Failure: different port 
http://data.example.com/dir/other.html       -> Failure: different hostname 
https://www.example.com/home/index.html:80   -> Failure: different protocol
ftp://www.example.com:21                     -> Failure: different protocol & port 
https://google.com/search?q=james+bond       -> Failure: different protocol, port & hostname 

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; 
    } 
}); 

Answer by Avery Cano

If you try to manipulate or read the contents of an iframe with a different origin, you will get an error like “Uncaught DOMException: Blocked a frame with origin «http://www.url.com» from accessing a cross-origin frame.”,When “new” stuff like postMessage is added, it takes us one step away from awful work-around hacks and makes all of our lives so much easier.,Iframes are never a joy to work with, but it’s hard to see any better alternative when you consider the security limitations when working with external content.,The idea is that you can use postMessage to send an API call to a different origin and receive an answer. Previously there was no (easy) way to make communication like that happen unless it was same-origin.

It allows you to control the player, e.g. starting the player:

myApp.set("playing", true);

Or restarting the video:
myApp.set('currentTime', 0);

Or for you to bind eventlisteners to video events (such as when the video is ending):

myApp.bind("player:video:ended", function(eventName, obj) {
 console.log("The event " + eventName + " fired and this object was returned: " + obj);
});

Answer by Dexter Bernal

Clicked actions like in the documentation are working in Chrome but not in firefox.
Currently seeing this DOMException in FireFox
SecurityError: Permission denied to access property «toJSON» on cross-origin object,I am also seeing this when trying to use Storybook Composition. It works fine within the original storybook, but I get the same error (Uncaught DOMException: Blocked a frame with origin from accessing a cross-origin frame.) at the same line whenever trying to load a story from the lower level «composed» storybook in the higher level «composing» storybook. Both storybook instances on 6.1.5, using basically stock webpack configs. If you’d like to verify/reproduce, here is a link to our Chromatic permalink. Anyone should be able to add this as a composed story and see the issue.,I solved this by opening storybook in an incognito window. It’s possible that Chrome plugins are messing with the browser.,@reywright This issue is still open, isn’t it? ? I think we were looking for a repro and the repro is to open built storybook from a file URL @ndelangen

      var data = (0, _telejson.stringify)({
        key: KEY,
        event: event
      }, {
        maxDepth: depth
      }); // TODO: investigate http://blog.teamtreehouse.com/cross-domain-messaging-with-postmessage
      // might replace '*' with document.location ?

      iframeWindow.postMessage(data, '*');
      return Promise.resolve(null);

Solution 1

Same-origin policy

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.

Origin is considered different if at least one of the following parts of the address isn’t maintained:

protocol://hostname:port/...

Protocol, hostname and port must be the same of your domain if you want to access a frame.

NOTE: Internet Explorer is known to not strictly follow this rule, see here for details.

Examples

Here’s what would happen trying to access the following URLs from http://www.example.com/home/index.html

URL                                             RESULT 
http://www.example.com/home/other.html       -> Success 
http://www.example.com/dir/inner/another.php -> Success 
http://www.example.com:80                    -> Success (default port for HTTP) 
http://www.example.com:2251                  -> Failure: different port 
http://data.example.com/dir/other.html       -> Failure: different hostname 
https://www.example.com/home/index.html:80   -> Failure: different protocol
ftp://www.example.com:21                     -> Failure: different protocol & port 
https://google.com/search?q=james+bond       -> Failure: different protocol, port & hostname 

Workaround

Even though same-origin policy blocks scripts from accessing the content of sites with a different origin, if you own both the pages, 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');
    

    The second argument to postMessage() can be '*' to indicate no preference about the origin of the destination. A target origin should always be provided when possible, to avoid disclosing the data you send to any other site.

  • 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.

Disabling same-origin policy in your browser

There already are some good answers about this topic (I just found them googling), so, for the browsers where this is possible, I’ll link the relative answer. However, please remember that disabling the same-origin policy will only affect your browser. Also, running a browser with same-origin security settings disabled grants any website access to cross-origin resources, so it’s very unsafe and should NEVER be done if you do not know exactly what you are doing (e.g. development purposes).

  • Google Chrome
  • Mozilla Firefox
  • Safari
  • Opera
  • Microsoft Edge: not possible
  • Microsoft Internet Explorer

Solution 2

Complementing Marco Bonelli’s answer: the best current way of interacting between frames/iframes is using window.postMessage, supported by all browsers

Solution 3

Check the domain’s web server for http://www.<domain>.com configuration for X-Frame-Options
It is a security feature designed to prevent clickJacking attacks,

How Does clickJacking work?

  1. The evil page looks exactly like the victim page.
  2. Then it tricked users to enter their username and password.

Technically the evil has an iframe with the source to the victim page.

<html>
    <iframe src='victim_domain.com'/>
    <input id="username" type="text" style="display: none;"/>
    <input id="password" type="text" style="display: none;"/>
    <script>
        //some JS code that click jacking the user username and input from inside the iframe...
    <script/>
<html>

How the security feature work

If you want to prevent web server request to be rendered within an iframe add the x-frame-options

X-Frame-Options DENY

The options are:

  1. SAMEORIGIN //allow only to my own domain render my HTML inside an iframe.
  2. DENY //do not allow my HTML to be rendered inside any iframe
  3. «ALLOW-FROM https://example.com/» //allow specific domain to render my HTML inside an iframe

This is IIS config example:

   <httpProtocol>
       <customHeaders>
           <add name="X-Frame-Options" value="SAMEORIGIN" />
       </customHeaders>
   </httpProtocol>

The solution to the question

If the web server activated the security feature it may cause a client-side SecurityError as it should.

Solution 4

For me i wanted to implement a 2-way handshake, meaning:
— the parent window will load faster then the iframe
— the iframe should talk to the parent window as soon as its ready
— the parent is ready to receive the iframe message and replay

this code is used to set white label in the iframe using [CSS custom property]
code:
iframe

$(function() {
    window.onload = function() {
        // create listener
        function receiveMessage(e) {
            document.documentElement.style.setProperty('--header_bg', e.data.wl.header_bg);
            document.documentElement.style.setProperty('--header_text', e.data.wl.header_text);
            document.documentElement.style.setProperty('--button_bg', e.data.wl.button_bg);
            //alert(e.data.data.header_bg);
        }
        window.addEventListener('message', receiveMessage);
        // call parent
        parent.postMessage("GetWhiteLabel","*");
    }
});

parent

$(function() {
    // create listener
    var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
    var eventer = window[eventMethod];
    var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";
    eventer(messageEvent, function (e) {
        // replay to child (iframe) 
        document.getElementById('wrapper-iframe').contentWindow.postMessage(
            {
                event_id: 'white_label_message',
                wl: {
                    header_bg: $('#Header').css('background-color'),
                    header_text: $('#Header .HoverMenu a').css('color'),
                    button_bg: $('#Header .HoverMenu a').css('background-color')
                }
            },
            '*'
        );
    }, false);
});

naturally you can limit the origins and the text, this is easy-to-work-with code
i found this examlpe to be helpful:
[Cross-Domain Messaging With postMessage]

Solution 5

There is a workaround, actually, for specific scenarios.

If you have two processes running on the same domain but different ports, the two windows can interact without limitations. (i.e. localhost:3000 & localhost:2000). To make this work, each window needs to change their domain to the shared origin:

document.domain = 'localhost'

This also works in the scenario that you are working with different subdomains on the same second-level domain, i.e. you are on john.site.com trying to access peter.site.com or just site.com

document.domain = 'site.com'

By explicitily setting document.domain; the browser will ignore the hostname difference and the windows can be treated as coming from the ‘same-origin’. Now, in a parent window, you can reach into the iframe: frame.contentWindow.document.body.classList.add('happyDev')

Comments

  • I am loading an <iframe> in my HTML page and trying to access the elements within it using Javascript, but when I try to execute my code, I get the following error:

    SecurityError: Blocked a frame with origin "http://www.<domain>.com" from accessing a cross-origin frame.
    

    Can you please help me to find a solution so that I can access the elements in the frame?

    I am using this code for testing, but in vain:

    $(document).ready(function() {
        var iframeWindow = document.getElementById("my-iframe-id").contentWindow;
    
        iframeWindow.addEventListener("load", function() {
            var doc = iframe.contentDocument || iframe.contentWindow.document;
            var target = doc.getElementById("my-target-id");
    
            target.innerHTML = "Found it!";
        });
    });
    

Recents

Prerequisites

  • Put an X between the brackets on this line if you have done all of the following:
    • Reproduced the problem in Safe Mode: https://flight-manual.atom.io/hacking-atom/sections/debugging/#using-safe-mode
    • Followed all applicable steps in the debugging guide: https://flight-manual.atom.io/hacking-atom/sections/debugging/
    • Checked the FAQs on the message board for common solutions: https://discuss.atom.io/c/faq
    • Checked that your issue isn’t already filed: https://github.com/issues?utf8=✓&q=is%3Aissue+user%3Aatom
    • Checked that there is not already an Atom package that provides the described functionality: https://atom.io/packages

Description

With Atom 1.47.0, a package that creates an <iframe> and loads a web page in it can no longer access the iframe’s contentWindow via JavaScript. An error occurs:

Uncaught SecurityError: Blocked a frame with origin "file://" from accessing a cross-origin frame.

Steps to Reproduce

We have a (non-public) Atom package that implements most of its UI not directly, but via a web application that it shows in an iframe.

More precisely, the Atom package

  1. creates a view in a dock
  2. creates an <iframe> in the view
  3. loads into the iframe a web application, which installs ‘API methods’ on its window object
  4. communicates with this web application by accessing the API methods of the iframe’s contentWindow

Note that the web application does not send X-Frame-Options or Content-Security-Policy headers.

Expected behavior:

The JavaScript code of the Atom package can access methods of the iframe’s contentWindow.

Actual behavior:

The access to the iframe’s methods is blocked, and a security error is thrown:

Uncaught SecurityError: Blocked a frame with origin "file://" from accessing a cross-origin frame.

Reproduces how often:

Every time.

Versions

This started to happen with Atom 1.47.0. The error does not occur with Atom 1.46.0 or earlier.

Additional Information

This stricter security policy is probably in place due to the upgrade to Electron 5 (or more precisely to Chrome 67+).

According to https://stackoverflow.com/questions/55898000/blocked-a-frame-with-origin-file-from-accessing-a-cross-origin-frame, Chrome 67 has added a ‘site isolation’ security feature, which needs to be disabled explicitly to allow these kinds of accesses.

I fully see why you’d want to have this security policy in place for a web browser. For us, it breaks our Atom package.

My questions:

  • Is it intended that an Atom package can no longer access JavaScript objects in the iframe it created?
  • If no, is it possible to disable this security policy?

Понравилась статья? Поделить с друзьями:
  • Ошибка uncaught referenceerror jquery is not defined
  • Ошибка undefined method for nil nilclass nomethoderror
  • Ошибка unb на стиральной машине haier что это такое
  • Ошибка undefined is not an object evaluating
  • Ошибка unb на стиральной машине haier как исправить ошибку