web-dev-qa-db-ja.com

ブラウザAPIがクロスドメインリクエストを制限するのはなぜですか?

XMLHttpRequestsは、クロスドメインで機能するためにCORSを必要とします。同様に、Webフォント、WebGLテクスチャ、およびその他のいくつかのものについても同様です。一般に、すべての新しいAPIにはこの制限があるようです。

どうして?

回避するのはとても簡単です。必要なのは、単純なサーバー側プロキシだけです。言い換えれば、サーバーサイドコードはクロスドメインリクエストを行うことを禁止されていません。クライアント側のコードはなぜですか?これはどのようにして誰かにセキュリティを与えるのでしょうか?

そして、それはとても一貫性がありません:私はXMLHttpRequestできませんが、<script src>または<link rel>または<img src>または<iframe>。 XHRなどを制限することで何が達成されますか?

36
Domenic

悪意のあるWebサイトにアクセスした場合、次のことを確認したいと思います。

  1. 私が使用している他のウェブサイトから私の個人データを読み取ることはできません。 gmail.comを読んでattacker.comを考えてください
  2. 私が使用している他のWebサイトでは、私に代わってアクションを実行できません。攻撃者.comがbank.comの私の口座から資金を送金すると考えてください

同一生成元ポリシーは最初の問題を解決します。 2番目の問題はクロスサイトリクエストフォージェリと呼ばれ、現在適用されているクロスドメイン制限では解決できません。

同一生成元ポリシーは、一般的に次のルールと一致しています-

  • ルール1:別のドメインから何も読めない
  • ルール2:別のドメインに好きなものを書き込むことができますが、ルール#1では応答を読み取ることができません。
  • ルール3:クロスドメインのGETリクエストとPOSTリクエストを自由に行うことができますが、HTTPヘッダーを制御することはできません

リストしたさまざまなものが上記のルールにどのように一致するかを見てみましょう。

  1. <img>タグを使用するとHTTPリクエストを作成できますが、画像を表示する以外に画像の内容を読み取る方法はありません。たとえば、これを<img src="http://bank.com/get/latest/funds"/>すると、リクエストは通過します(ルール2)。しかし、攻撃者が私の残高を確認する方法はありません(ルール1)。

  2. <script>タグはほとんど<img>のように機能します。 <script src="http://bank.com/get/latest/funds">のようなことをすると、リクエストは通過します。また、ブラウザは応答をJavaScriptとして解析しようとし、失敗します。

  3. JSONPと呼ばれる<script>タグの悪用はよく知られています。この場合、クロスドメインサーバーと共謀して、クロスドメインを「読み取る」ことができます。ただし、クロスドメインサーバーの明示的な関与がなければ、<script>タグを介して応答を読み取ることはできません。

  4. スタイルシートの<link>は、応答がCSSとして評価されることを除いて、ほとんど<script>タグと同じように機能します。一般に、応答を読み取ることはできません-応答が何らかの形で整形式のCSSである場合を除きます。

  5. <iframe>は本質的に新しいブラウザウィンドウです。クロスドメインiframeのHTMLを読み取ることはできません。ちなみに、クロスドメインiframeのURLは変更できますが、そのURLを読み取ることはできません。上記の2つのルールに従っていることに注目してください。

  6. XMLHttpRequestは、HTTPリクエストを作成するための最も用途の広い方法です。これは完全に開発者の管理下にあります。ブラウザは応答に対して何もしません。たとえば、<img><script>、または<link>の場合、ブラウザは特定の形式を想定し、通常はそれを適切に検証します。ただし、XHRには、規定の応答形式はありません。そのため、ブラウザは同じOriginポリシーを適用し、クロスドメインWebサイトで明示的に許可されていない限り、応答を読み取れないようにします。

  7. font-face経由のフォントは異常です。 AFAIK、Firefoxのみがオプトイン動作を必要とします。他のブラウザでは、画像を使用するのと同じようにフォントを使用できます。

要するに、同一生成元ポリシーは一貫しています。クロスドメインリクエストを行う方法を見つけた場合そしてクロスドメインウェブサイトからの明示的な許可なしにレスポンスを読む-あなたは世界中で見出しを作るでしょう。

[〜#〜] edit [〜#〜]:サーバー側プロキシでこれらすべてを回避できないのはなぜですか?

Gmailでパーソナライズされたデータを表示するには、ブラウザからのCookieが必要です。一部のサイトでは、資格情報がブラウザに保存されるHTTP基本認証を使用しています。

サーバー側プロキシは、Cookieまたは基本認証資格情報のいずれにもアクセスできません。そのため、リクエストを送信できたとしても、サーバーはユーザー固有のデータを返しません。

59

このシナリオを考えてみましょう...

  1. あなたは私の悪意のあるウェブサイトに行きます。
  2. 私のサイトはあなたの銀行のウェブサイトにXHRを作成し、銀行振込のフォームを要求します。
  3. XHRは、CSRFを防止するトークンを読み取り、セキュリティトークンと一緒にフォームをPOSTし、金額を私のアカウントに送金します。
  4. (I)利益!!!

同一生成元ポリシーが存在しない場合でも、そのフォームをPOSTできますが、CSRFを防ぐCSRFトークンをリクエストすることはできません。

サーバー側のコードは、クライアントのコンピューターでは実行されません。

3
alex

XHRの主な問題は、リクエストを送信できるだけでなく、レスポンスを読み取ることもできることです。ほぼ恣意的なリクエストの送信はすでに可能でした。しかし、彼らの回答を読むことはそうではありませんでした。そのため、元のXHRではクロスオリジンリクエストがまったく許可されていませんでした。

その後、XHRを使用したクロスオリジンリクエストの需要が発生したときに、特定の条件下でクロスオリジンリクエストを許可するようにCORSが確立されました。 1つの条件は、特定のリクエストメソッド、リクエストヘッダーフィールド、およびユーザー資格情報を含むリクエストには、サーバーがリクエストを許可するかどうかをクライアントが確認できる、いわゆるプリフライトリクエストが必要なことです。これにより、サーバーは特定のオリジンのみにアクセスを制限することができます。そうしないと、どのオリジンもリクエストを送信できます。

2
Gumbo