web-dev-qa-db-ja.com

CORSを悪用するために悪意のあるコードが "Origin"ヘッダーをスプーフィングするのを防ぐにはどうすればよいですか?

Foo.comのページで実行されているクライアント側スクリプトがbar.comのデータをリクエストする場合、リクエストでヘッダー_Origin: http://foo.com_を指定する必要があり、barは_Access-Control-Allow-Origin: http://foo.com_。

サイトroh.comからの悪意のあるコードがヘッダー_Origin: http://foo.com_を単純にスプーフィングしてbarからページをリクエストするのを防ぐために何がありますか?

108
Jay Lamont

ブラウザはOriginヘッダーの設定を制御しており、ユーザーはこの値を上書きできません。そのため、ブラウザから偽装されたOriginヘッダーは表示されません。悪意のあるユーザーはOriginヘッダーを手動で設定するcurlリクエストを作成できますが、このリクエストはブラウザーの外部から送信され、ブラウザー固有の情報(Cookieなど)を持たない可能性があります。

要確認:CORSはセキュリティではありません。サイトを保護するためにCORSに依存しないでください。保護されたデータを提供している場合は、CookieまたはOAuthトークンまたはOriginヘッダー以外のものを使用して、そのデータを保護します。CORSのAccess-Control-Allow-Originヘッダーは、オリジンはクロスオリジンリクエストを許可する必要があります。

119
monsur

TLDR:悪意のあるコードがオリジンをスプーフィングするのを止めるものは何もありません。その場合、サーバーはそれを知ることはなく、リクエストに応じて行動します。時々、それらのリクエストは高価です。そのため、セキュリティの種類の代わりにCORSを使用しないでください。


私は最近CORSをいじくり回しており、同じ質問を自問しました。私が見つけたのは、ブラウザは、偽装されたCORSリクエストを検出したときにそれを知るのに十分賢いかもしれないが、あなたのサーバーはそれほど賢くないということです。

私が最初に見つけたのは、OriginヘッダーがHTTP 禁止ヘッダー名 であり、プログラムで変更できないことです。つまり、 Google Chromeのヘッダーの変更 を使用して、約8秒で変更できます。

これをテストするために、2つのクライアントドメインと1つのサーバードメインをセットアップしました。サーバーにCORSホワイトリストを追加し、クライアント1からのCORSリクエストを許可しましたが、クライアント2からは許可しませんでした。両方のクライアントをテストし、クライアント1のCORSリクエストは成功しましたが、クライアント2は失敗しました。

次に、クライアント1に一致するようにクライアント2のOriginヘッダーを偽装しました。サーバーは、スプーフィングされたOriginヘッダーを受信し、ホワイトリストチェックに合格しました(または、ガラスが半分空っぽの男なら失敗しました)。その後、サーバーは、消費するように設計されたすべてのリソース(データベース呼び出し、高価な電子メールの送信、さらに高価なsmsメッセージの送信など)を消費することにより、忠実に実行しました。それが完了すると、サーバーはスプーフィングされたAccess-Control-Allow-Originヘッダーをブラウザに喜んで送り返しました。

私が読んだドキュメントでは、受け取ったAccess-Control-Allow-Origin値は、リクエストで送信されたOrigin値と正確に一致する必要があると述べています。それらは一致したので、Chromeで次のメッセージを見て驚いた。

XMLHttpRequestはhttp://server.dev/testをロードできません。 'Access-Control-Allow-Origin'ヘッダーの値はhttp://client1.devで、指定されたOriginと等しくありません。したがって、Origin http://client2.devはアクセスを許可されていません。

私が読んだ文書は正確ではないようです。 Chromeの[ネットワーク]タブには、リクエストヘッダーとレスポンスヘッダーの両方がhttp://client1.devとして明確に表示されますが、エラーでChromeが実際のOriginがhttp://client2.devこの時点では重要ではありません。サーバーはすでにスプーフィングされたリクエストを受け入れ、私のお金を使っていたためです。

26
Nocturno

謙虚なまとめ:

Q: Same Origin Policy(SOP)はブラウザーによってのみ強制されますか?
A:はい。ブラウザ内で行うすべての呼び出しについて、SOPはブラウザによって確実に適用されます。サーバーはリクエストの送信元をチェックする場合としない場合があります。

Q:リクエストがSOPに準拠していない場合、ブラウザはそれをブロックしますか?
A:いいえ、ブラウザの権限を超えています。ブラウザは、Origin間のクロスリクエストを送信し、応答がAccess-Control- *ヘッダーを介してサーバーによって合法的に通知されるかどうかを確認するために待機します。サーバーがAccess-Control-Allow-Originヘッダーを返送しない、発信者の発信元をエコーバックしない、またはヘッダーに*を返送しない場合、ブラウザーができることは、提供を控えることです。呼び出し元への応答。

Q:Originをスプーフィングできないということですか?
A:ブラウザーでスクリプトを使用する場合、ブラウザーの制御下にあるため、Originをオーバーライドできません。ただし、自分自身をハックしたい場合は、ブラウザー拡張機能またはマシンにインストールした他のツールを使用して、ブラウザーからの呼び出しを改ざんすることができます。 HTTPcurlC#などを使用してPython呼び出しを発行し、Originヘッダーを変更してサーバーをトリックすることもできます。

Q:では、Originを変更してサーバーをだませる場合、CORSは安全ではないということですか?
A:CORSは、セキュリティについては黙っています。つまり、リクエストの認証と承認です。リクエストを検査し、Cookieやヘッダーなどのメカニズムでリクエストを認証/承認するのはサーバー次第です。そうは言っても、XSSのような攻撃の場合には、もう少し保護できます。

例: Webサイトにログインし、悪意のあるスクリプトコードが銀行のWebサイトにリクエストを送信して残高を照会しようとするとします。銀行のWebサイトは、Webサイトからの資格情報を信頼しているため、要求が認証され、悪意のあるコードを対象とするHTTP応答が発行されます。銀行のWebサイトがエンドポイントを他のオリジンと共有することに関心がない場合、応答にAccess-Control-Allow-Originヘッダーは含まれません。これで、リクエストが到着すると、ブラウザはリクエストがクロスオリジンのものであることを認識しますが、サーバーがウェブサイトとリソース(ここでは残高クエリエンドポイント)を共有することに満足していることをレスポンスは示しません。そのため、フローが中断され、返される結果が悪意のあるコードに到達することはありません。

2
Alireza