web-dev-qa-db-ja.com

標準のコンテンツタイプのPOSTリクエストのCORSにプリフライトがないのはなぜですか?

CORS POSTリクエストのセキュリティ面について少し混乱しています。このトピックに関する情報がオンラインで失われていることは知っていますが、質問に対する明確な答えを見つけることができませんでした。

私が正しく理解していれば、同一生成元ポリシーの目標はCSRF攻撃を防ぐことであり、CORSの目標は、サーバーが他のサイト(オリジン)でホストされているアプリケーションとデータを共有することに同意した場合にのみリソース共有を有効にすることです。 )。

HTTPは、POSTリクエストは「安全」ではないことを指定します。つまり、新しいコメントを追加するなどして、サーバーの状態を変更する可能性があります。HTTPメソッドPOSTを使用してCORSリクエストを開始すると、ブラウザはリクエストのコンテンツタイプが非標準の場合(または非標準のhttpヘッダーがある場合)にのみ、「安全な」プリフライトリクエストを実行します。したがって、POST標準のコンテンツタイプのリクエストと標準ヘッダーが実行され、サーバーに悪影響を与える可能性があります(ただし、要求しているスクリプトが応答にアクセスできない場合があります)。

すべてのフォームにランダムトークンを追加するこの手法があり、サーバーはこれをすべての「安全でない」要求の一部にする必要があります。スクリプトがリクエストを偽造しようとすると、次のいずれかになります。

  1. ランダムトークンがなく、サーバーがリクエストを拒否した、または
  2. ランダムトークンが定義されているフォームにアクセスしようとします。ランダムトークンを使用したこの応答には、ブラウザがこの応答への悪意のあるスクリプトアクセスを許可しないように、適切なヘッドフィールドが必要です。また、この場合、試行は失敗します。

私の結論は、偽造されたPOST標準のコンテンツタイプとヘッダーを持つリクエストに対する唯一の保護は、上記の手法(または同様の手法)であるということです。 PUTまたはDELETE、またはa POST json-contentの場合、CORSは「安全な」OPTIONSリクエストを実行するため、この手法を使用する必要はありません。

CORSの作成者がこれらのPOSTをプリフライトリクエストから除外したため、上記の手法を採用する必要があったのはなぜですか?

20
sauerburger

CORS-プリフライトリクエストを導入する動機は何ですか? およびその他の回答を参照してください。

CORSがブラウザにapplication/x-www-form-urlencodedmultipart/form-data、またはtext/plainコンテンツタイプのプリフライトを要求しない理由は、そうすると、ブラウザが持っているものよりもCORSが制限されるためです。すでに常に許可されています(そして、CORSなしですでに可能であったことに新しい制限を課すことはCORSの意図ではありません)。

つまり、CORSでは、POST以前にクロスオリジンで実行できたリクエストはプリフライトされません。これは、ブラウザがCORSが存在する前にすでに許可しており、サーバーがそれらを認識しているためです。したがって、CORSはそれらについて何も変更しません。 「古い」タイプのリクエスト。

しかし、CORSの前は、ブラウザはクロスオリジンapplication/json POST)を実行することをまったく許可していなかったため、サーバーはそれらを受信しないと想定することができました。 CORSプリフライトは、「古い」リクエストではなく、これらのタイプの「新しい」リクエストに必要です。これは、サポートに明示的にオプトインする必要がある別の「新しい」タイプのリクエストであることをサーバーに通知するためです。 。

26
sideshowbarker