プリフライトリクエストを導入した動機は何ですか?
ブラウザが特定のリクエストを送信する前にCORS対応サーバーを処理していることを確認できるように、プリフライトリクエストが導入されました。これらのリクエストは、潜在的に危険(状態を変える)と新しい(同じ発生元ポリシーのためにCORSの前には不可能であった)の両方であるリクエストとして定義されました。プリフライト要求を使用するということは、CORSが可能にする潜在的に危険な新しいタイプの要求にサーバーが(プリフライトに適切に応答することによって)オプトインする必要があることを意味します。
それが仕様のこの部分の意味です。「この仕様が存在する前に特定のユーザーエージェントから発信できなかったクロスオリジンリクエストからリソースを保護するために、プリフライトリクエストが行われ、リソースがこの仕様を認識していることを確認します。」
例を挙げてもらえますか?
ブラウザユーザーがの銀行サイトにログインしているとしましょうA.com
。悪意のあるB.com
ユーザーに移動すると、そのページにはDELETE
リクエストをに送信しようとするJavascriptが含まれA.com/account
ます。ユーザーはにログインしA.com
ているため、送信されたリクエストには、ユーザーを識別するCookieが含まれます。
CORSが導入される前は、ブラウザの同一生成元ポリシーによって、このリクエストの送信がブロックされていました。しかし、CORSの目的は、この種のクロスオリジンコミュニケーションを可能にすることなので、もはや適切ではありません。
ブラウザは単にを送信しDELETE
、サーバーにその処理方法を決定させることができます。しかしA.com
、CORSプロトコルを認識していない場合はどうなりますか?それは先に進んで危険を実行するかもしれませんDELETE
。ブラウザーのSame Origin Policyにより、そのような要求を受信することはできないため、このような攻撃に対して強化されていない可能性があると想定されていた可能性があります。
このようなCORS非対応サーバーを保護するために、このプロトコルでは、ブラウザが最初にプリフライト要求を送信する必要があります。この新しい種類のリクエストは、CORS対応サーバーのみが適切に応答できるため、ブラウザは実際のを送信しても安全かどうかを確認できますDELETE
。
なぜブラウザがこれほど面倒なのか、攻撃者DELETE
は自分のコンピュータからリクエストを送信できないのですか?
もちろん、そのようなリクエストにはユーザーのCookieは含まれません。これを防ぐために設計された攻撃は、ブラウザーが要求と共に他のドメインのCookie(特にユーザーの認証情報)を送信するという事実に依存しています。
以下のようなその音クロスサイトリクエストフォージェリサイト上のフォーム、B.com
缶POST
にA.com
、ユーザーのクッキーとは、ダメージを与えます。
そのとおり。これを説明する別の方法は、CORS非対応サーバーのCSRF攻撃面を増加させないようにプリフライト要求が作成されたことです。
しかし、プリフライトを必要としない「単純な」リクエストの要件を見ると、それPOST
はまだ許可されていることがわかります。DELETE
!のように、状態を変更してデータを削除できます。
それは本当だ!CORSは、CSRF攻撃からサイトを保護しません。また、CORSがないと、CSRF攻撃からも保護されません。プリフライトリクエストの目的は、CSRFへの露出を、CORS以前の世界にすでに存在するものに制限することです。
はぁ。OK、プリフライトリクエストの必要性を不本意に受け入れます。しかし、なぜサーバー上のすべてのリソース(URL)に対してこれを行う必要があるのでしょうか。サーバーはCORSを処理するか、処理しません。
よろしいですか?複数のサーバーが単一のドメインに対する要求を処理することは珍しくありません。例えば、要求A.com/url1
が1種類のサーバーでA.com/url2
処理され、要求が別の種類のサーバーで処理される場合があります。単一のリソースを処理するサーバーがそのドメイン上のすべてのリソースについてセキュリティを保証できるのは、一般的には当てはまりません。
いいね。妥協しましょう。これらのURLへの追加のプリフライト要求を回避できるように、サーバーが発言できるリソースを正確に示すことができる新しいCORSヘッダーを作成しましょう。
良いアイデア!実際、ヘッダーAccess-Control-Policy-Path
はこの目的のためだけに提案されました。最終的に、しかし、それは、仕様書のうち残っていたどうやら一部のサーバーが誤ってブラウザに安全なように見えたパスへの要求が実際に壊れたサーバー上で安全ではないような方法で、URIの仕様を実装しているため。
これは、パフォーマンスよりもセキュリティを優先し、既存のサーバーを危険にさらすことなくブラウザーがCORS仕様をすぐに実装できるようにする慎重な決定でしたか?または、特定の時間に特定のサーバーのバグに対応するために、帯域幅を浪費し、レイテンシを2倍にするためにインターネットを破滅させるのは近視眼でしたか?
意見は異なります。
少なくとも、ブラウザは単一のURLのプリフライトをキャッシュしますか?
はい。おそらくそれほど長くはありませんが。WebKitブラウザーでは、プリフライトの最大キャッシュ時間は現在10分です。
はぁ。サーバーがCORSに対応していて、プリフライトリクエストによる保護が不要であることを知っている場合、それらを回避する方法はありますか?
あなたの唯一の現実的な選択肢は、「単純な」リクエストの要件を確実に満たすことです。それは、他の方法で含める(のようなX-Requested-With
)カスタムヘッダーの除外、の横にあるContent-Type
、などを意味する場合があります。
CORS仕様では、unsafeを含む「単純な」要求の拒否に対応していないため、何をする場合でも、適切なCSRF保護が実施されていることを確認する必要がありますPOST
。仕様にあるように、「単純なリクエストが取得以外の意味を持つリソースは、クロスサイトリクエストフォージェリから保護する必要があります」。