web-dev-qa-db-ja.com

SecurityError:Originを含むフレームがクロスOriginフレームにアクセスするのをブロックしました

HTMLページに<iframe>をロードし、Javascriptを使用してその中の要素にアクセスしようとしましたが、コードを実行しようとすると、次のエラーが発生します。

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

フレーム内の要素にアクセスできるように、解決策を見つけてください。

私はこのコードをテストに使用していますが、無駄です。

$(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!";
    });
});
418
mubashermubi

同起源ポリシー

CORS と混同しないでください!

ca n't JavaScriptを使用して異なるOriginで<iframe>にアクセスすると、できればセキュリティ上の大きな欠陥になります。 same-Origin policyブラウザは、異なるOriginのフレームにアクセスしようとするスクリプトをブロックしますの場合。

住所の次の部​​分の少なくとも1つが維持されていない場合、起源は異なると見なされます。

<protocol>://<hostname>:<port>/path/to/page.html 

Protocolhostname、およびportは、フレームにアクセスする場合、ドメインと同じでなければなりません。

http://www.example.com/home/index.htmlから次のURLにアクセスしようとするとどうなりますか

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.html -> Failure: different protocol 
ftp://www.example.com:21                     -> Failure: different protocol & port 
https://google.com/search?q=james+bond       -> Failure: different hostname & protocol 

Workaround

Same-Originポリシーは、異なるOriginのサイトのコンテンツへのスクリプトのアクセスをブロックしますが、両方のページを所有している場合、 window.postMessage とその相対messageイベントを使用してこの問題を回避できます次のように、2つのページ間でメッセージを送信します。

  • メインページで:

    let frame = document.getElementById('your-frame-id'); 
    
    frame.contentWindow.postMessage(/*any variable or object here*/, '*'); 
    
  • <iframe>(メインページに含まれています):

    window.addEventListener('message', function(event) { 
    
        // IMPORTANT: Check the Origin of the data! 
        if (~event.Origin.indexOf('http://yoursite.com')) { 
            // The data has been sent from your site 
    
            // The data sent with postMessage is stored in event.data 
            console.log(event.data); 
        } else { 
            // The data hasn't been sent from your site! 
            // Be careful! Do not use it. 
            return; 
        } 
    }); 
    

このメソッドは両方向に適用でき、メインページにもリスナーを作成し、フレームから応答を受け取ります。同じロジックをポップアップに実装することもできます。基本的には、メインページで生成される新しいウィンドウ(例: window.open() を使用)も同様です。

yourブラウザで同一生成元ポリシーを無効にする

このトピックについては既にいくつかの良い回答があります(グーグルで見つけたばかりです)ので、これが可能なブラウザーについては、相対的な回答をリンクします。ただし、same-Originポリシー(またはCORS)を無効にすると、yourbrowserのみに影響することに注意してください。また、同じ起源のセキュリティ設定を無効にしたブラウザを実行すると、すべてのウェブサイトにクロス起源のリソースへのアクセスが許可されるため、これは非常に安全ではなく、開発目的のみに行う必要があります

691
Marco Bonelli

Marco Bonelliの答えを補完する:フレーム/ iframe間でやり取りするための現在の最良の方法は window.postMessageを使用することです - すべてのブラウザでサポートされています - /

46
Geert

ドメインのWebサーバーでhttp://www.<domain>.comX-Frame-Options設定を確認してください。これはclickJacking攻撃を防ぐために設計されたセキュリティ機能です。

ClickJackingはどのように機能しますか?

  1. 悪のページは、被害者のページとまったく同じように見えます。
  2. それからそれはユーザー名とパスワードを入力するようにユーザーをだましました。

技術的には、悪は犠牲者ページへのソースを持つiframeを持っています。

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

セキュリティ機能のしくみ

Webサーバのリクエストがiframe内にレンダリングされないようにしたい場合は、 x-frame-options を追加します。

XフレームオプションDENY

オプションは以下のとおりです。

  1. SAMEORIGIN //自分のドメインにのみ許可し、自分のHTMLをiframe内にレンダリングする。
  2. DENY // HTMLをiframe内にレンダリングすることを許可しない
  3. "ALLOW-FROM https://example.com/ " //特定のドメインに自分のHTMLをiframe内に表示させる

これはIIS configの例です。

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

質問に対する解決策

Webサーバがセキュリティ機能を有効にした場合、クライアント側のSecurityErrorが発生する可能性があります。

12
Shahar Shokrani

私にとっては、双方向ハンドシェイクを実装したいと思っていました。
- 親ウィンドウはiframeよりも速くロードされます
- 準備ができ次第、iframeは親ウィンドウと対話します
- 親はiframeメッセージを受信して​​再生する準備ができています

このコードは、 [CSSカスタムプロパティ] を使用してiframeにホワイトラベルを設定するために使用されます。
コード:
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","*");
    }
});

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

当然あなたは起源とテキストを制限することができます、これは働きやすいコードです
この例文は参考になりました。
[postMessageによるクロスドメインメッセージング]

6
Yakir Manor