12

http://localhost/MyApp一部のパーツがIFRAMESを介してレンダリングされるアプリケーション( )があります。これらのiframedパーツは、アプリケーションのDOMの他の部分とは関係がないため、sandbox属性を適用しました。

IFRAMEは次のように宣言されます。

<iframe src="/MyApp/en/html/action?id=1" sandbox="allow-forms allow-scripts" seamless="seamless"></iframe>

iframedページには、同じWebアプリケーションに対してAJAX呼び出しを行うボタンがありますがHTTP GET、ブラウザでは、HTTP OPTIONSとして表示されるが発行されCancelled、エラーが発生します。

XMLHttpRequest cannot load http://localhost/MyApp/en/data/action?id=1. Cannot make any requests from null.
Ajax State 0 Error: HTTP 0 

属性にを追加するallow-same-originと、機能します。ここで読んだsandbox限り、AJAX呼び出しに影響を与えることは想定されていませんでした。

なぜこうなった?パス/MyApp/en/html/actionをIFRAME全体の起点と見なし、前のレベルへのリクエストをブロックしていますか?

乾杯。

4

1 に答える 1

27

これがAjaxに影響を与える理由は、Ajaxが同一生成元ポリシールールによって管理されており、サンドボックス化すると、iframeコンテンツを別のオリジンからのものであるかのように扱うようにブラウザーに効果的に指示しているためです。同じ記事を引用する:

  • ユニークな起源の治療。すべてのコンテンツは、固有のオリジンの下で扱われます。コンテンツはDOMをトラバースしたり、Cookie情報を読み取ったりすることはできません。

これは、同じドメインからのコンテンツでさえ、各IFRAMEコンテンツが一意のオリジンとして表示されるため、クロスドメインポリシーで扱われることを意味します。

埋め込まれたコンテンツは、情報の表示のみが許可されています。IFRAME内で、ホスティングWebサイトを危険にさらしたり、ユーザーの信頼を利用したりする可能性のある他のアクションを実行することはできません。

つまり、属性でallow-same-origininを省略sandboxすると、サンドボックス化されたページが別のドメインに属しているものとして扱われます(実際には、nullオリジンを持つものとして扱われます)。Ajaxリクエストを行うのは意味がないためnull、サンドボックス化されたページはAjax呼び出しをまったく行うことができません(許可された場合localhost、親ページからの呼び出しと区別がつかなくなり、サンドボックス化の目的が損なわれます)。

追加情報

別のドメインにAjax呼び出しを行おうとすると、明らかに失敗します。

<script src="http://code.jquery.com/jquery.min.js"></script>
<script>
    console.log(location.host);
    $.post('https://google.com/',{},function() { });
</script>

ただし、どのように失敗するかは、使用するサンドボックス属性によって異なります。上記のページをに埋め込むと、次のようiframeallow-same-originコンソールに出力されます。

localhost
XMLHttpRequest cannot load https://google.com/. Origin http://localhost is not allowed by Access-Control-Allow-Origin.

...そしてあなたがそれなし allow-same-originでそれを埋め込むならば:

localhost
XMLHttpRequest cannot load https://google.com/. Cannot make any requests from null.

location.host両方ともとして報告されlocalhostますが、一方は発生源であると見なし、http://localhostもう一方は発生源であると見なしたことに注意nullしてください(例で発生したのと同じエラーメッセージが表示されます)。

推論

同じドメインのサンドボックス化されたコンテンツからのAjax呼び出しをブロックすることがなぜそれほど重要なのですか?記事で説明されているように:

同じドメインのコンテンツは安全でなければならないというのは理にかなっています。ここでのリスクは主に、 IFRAMEで再ホストされるユーザー生成コンテンツに起因します。

例を挙げましょう。Facebookがユーザーが自分のページに小さなHTML5アニメーションを投稿できるようにすることを決定したとします。それらを独自のサーバーに保存し、表示時にサンドボックス化しますallow-scripts(アニメーションが機能するにはスクリプトが必要なため)が、他のすべては拒否されたままにします(特にallow-same-origin、ユーザーコードが親ページを台無しにしたくないため) )。Ajax呼び出しもデフォルトでブロックされていなかった場合はどうなりますか?

マロリーは、次の要素で構成される「アニメーション」を作成します。

  1. API(Open Graphなど)を使用してFacebookへのAjax呼び出しを実行します。サーバーは、リクエストが発信元としてのページから来たことをすべて知っているので、喜んで呼び出しを受け入れますhttps://facebook.com

  2. 返されたデータをクエリ文字列として使用して、自分のサーバーを指すURIを作成しsrc、サンドボックス化されたページの画像として設定します。

アリスがマロリーのプロフィールにアクセスしてアニメーションを見ると、上記のスクリプトが実行されます。

  1. Ajax呼び出しは、Aliceがログオンしている間、Aliceのブラウザーで実行されます。サーバーは呼び出しがどこから来たのか(メインページまたは埋め込みページ)を知らないため、個人情報の取得を含め、要求されたすべてのことを実行します。

  2. 要素がマロリーのURIで作成される場合img、画像は同一生成元ポリシーから免除されるため、ブラウザは通常どおり「画像」を読み込もうとします。

  3. URIのクエリ文字列にはアリスのプライベート情報が含まれているため、マロリーのサーバーはそれを保存して、必要な画像を返すことができます。現在、マロリーはアリスの個人情報を持っており、アリスは何も疑っていません。

于 2013-01-31T06:14:57.570 に答える