悪意のあるコードがCORSを悪用するために「Origin」ヘッダーを偽装するのを防ぐにはどうすればよいですか?


142

私が理解している方法では、foo.comのページで実行されているクライアント側のスクリプトがbar.comのデータをリクエストする場合、リクエストでヘッダーを指定し、Origin: http://foo.comバーがで応答する必要がありますAccess-Control-Allow-Origin: http://foo.com

サイトroh.comからの悪意のあるコードがヘッダーOrigin: http://foo.comを偽装してバーからページを要求するのを防ぐ方法は何ですか?


2
ポイントは、ページの提供元の元のドメイン(ここではfoo.com)がAccess-Control-Allow-Originヘッダーを提供する必要があるか、そうでない場合、ブラウザーがへのリクエストを許可しないことbar.comです。
Chris Hayes

2
この投稿を読むことは、ブラウザー、オリジンサーバー、ターゲットサーバー間のcorsプロセスを理解するのに非常に役立ちました。html5rocks.com/en/tutorials/cors
brendonparker

5
@ChrisHayesそれはCORSがまったく機能しない方法です。仕様、またはこの件に関するこのすばらしいMDN wikiページを見るとこれについてもう少し詳しく読むことができます。
レイニコラス2014年

1
@brendonparkerはい、それは素晴らしい記事です。その作者は、SOに関するCORSの多くの質問に回答し、enable-cors.orgも維持しています
レイニコラス2014年

4
@RayNicholus興味深いことに、私は明らかに道を外れていました。リンクをありがとう。私のコメントへの投票から判断すると、この妄想で苦しんでいるのは私だけではありません。私はそれらの2人が戻って学び(そして彼らの投票を削除して)くれることを願っています。
Chris Hayes

回答:


149

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

注意:CORSはセキュリティではありません。CORSに依存してサイトを保護しないでください。保護されたデータを提供する場合は、Cookie、OAuthトークン、またはOriginヘッダー以外のものを使用して、そのデータを保護します。Access-Control-Allow-OriginCORS のヘッダーは、どのオリジンがクロスオリジンリクエストを作成できるようにするかを指示するだけです。それ以上これに依存しないでください。


3
これは非常に理にかなっています。ブラウザがJavaScriptによるOriginヘッダーのオーバーライドを許可しない場合、問題はありません。ブラウザの外部からリクエストを実行している場合、Cookieはありません。私が読んでいたすべてのドキュメントで、Originヘッダーをオーバーライドできなかったと明示的に言ったところはないので、私は混乱したと思います。ありがとう!
Jay Lamont

41
誰かがなりすましをしたい場合、そうすることができます。ほぼすべてのスクリプト言語を使用して、httpリクエストを作成できます。PerlとPythonには、これを非常に簡単にするhttpライブラリがあります。ライブラリはCookieを保存および送信し、任意のヘッダーを追加して、多くのデバッグ情報を提供します。したがって、CORSヘッダーは、ブラウザーで両方にログインしているときに、別のドメインの銀行口座に対して悪質な行為を行うことをフォーラムで悪意のあるJavaScriptが実行することを困難にするためのものです。
Mnebuerquo 2014年

9
明確にするために、悪意のあるユーザーは、Originヘッダーを手動で制御できるようにパッチが適用されたブラウザーインスタンスを生成し、通常のユーザー、Cookie、AJAXなどを完全に偽装することができます。
ジョーダンリーガー、2014年

10
「ブラウザーはOriginヘッダーの設定を制御しており、ユーザーはこの値をオーバーライドできません。」リクエストがブラウザを離れたら、Fiddler2やCharlesなどのツールを使用してヘッダーを変更するのは非常に簡単だと思います。
Asa

3
悪意のあるユーザーは、Originヘッダーを手動で制御できるように、パッチが適用されたブラウザーインスタンスを単純に生成することができます。私にとって)、なぜディスクから直接Cookieを直接読み取らないのですか?彼らはあなたが知っているプレーンテキストで保存されています。実生活では、クロスサイトスクリプティングは実際の脅威ですが、攻撃のシナリオは、人為的で実際的ではありません。
Stijn de Witt 2017

35

TLDR:悪意のあるコードがオリジンを偽装するのを妨げるものは何もありません。それが発生すると、サーバーはそれを知ることはなく、リクエストに応じて動作します。時々それらの要求は高価です。したがって、セキュリティの種類の代わりにCORSを使用しないでください。


最近CORSをいじってみましたが、私も同じ質問をしました。私が見つけたのは、ブラウザーはスプーフィングされたCORS要求を認識するのに十分なほどスマートである可能性があることですが、サーバーはそれほどスマートではありません。

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

これをテストするために、2つのクライアントドメインと1つのサーバードメインを設定しました。サーバーにCORSホワイトリストを含めました。これにより、クライアント1からのCORSリクエストは許可されましたが、クライアント2からのCORSリクエストは許可されませんでした。両方のクライアントをテストしました。実際、クライアント2が失敗してもクライアント1のCORSリクエストは成功しました。

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

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

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

私が読んだドキュメントは正確ではないようです。Chromeのネットワークタブには、リクエストヘッダーとレスポンスヘッダーの両方が明確に表示されhttp://client1.devますが、エラーでChromeが実際の発信元が何であるかを認識しておりhttp://client2.dev、応答を正しく拒否していることがわかります。サーバーはすでにスプーフィングされたリクエストを受け入れており、私のお金を費やしていたので、現時点ではどちらでもかまいません


2
@Nocturno、例をありがとう。私の見解を追加しましょう。CORSはブラウザの安全機能に関連しています。安全なブラウザが元の状態から変更された場合、ブラウザに安全機能がない可能性があると解釈できます。
LukaŽitnik2017年

10
まったく見事ではありません。CORSの要点を完全に逃しています。ユーザーのマシンからのリクエストを傍受する立場にある場合は、そのCookieを読み取り、キーロガー、ウイルス、およびその他すべての実際の脅威をインストールできます。CORSは、サイトAにログインした正直なユーザーを、何らかの理由でサイトBに挿入された悪意のあるスクリプトから保護するためのものです。サイトBのスクリプト(サイトBによって正しくエスケープされなかったフォーラム投稿のJavascriptのスニペットである可能性があります)は、サイトAからセッションクッキーを使用してユーザーのアカウント(たとえば、削除のものなど)の下で、サイトA上のアクション、
Stijnデウィット

3
これはクロスサイトスクリプティングと呼ばれ、CORSを使用せずにユーザーのマシンを制御する必要なく実行できます。それがポイントです。ユーザーのマシンを制御する必要はありませんでした。サイトAへのリクエストを行うときに、ブラウザがセッションCookieをリクエストに自動的に追加していたため、実際には他のスクリプトからのリクエストであるように見えたためです。地点。Same-Originポリシーはそれを防止し、CORSは、それらが異なるオリジンにある場合でもアクセスを許可されるべきドメインをホワイトリストに登録するために使用されます。
Stijn de Witt 2017

3
@Nocturnoええ、私は多分ちょっと粗雑だったので、ごめんなさい。元のポイントはそのままです。Same-Originポリシーはブラウザのセキュリティ機能であり、CORSは一部のドメインをホワイトリストに登録することによってそのセキュリティを弱めるメカニズムです。OPは、Originヘッダーのスプーフィングが「攻撃」として実際に実行可能ではないことを理解する必要があります。これは、curlなどでは得られないものをもたらさないためです。
Stijn de Witt

3
@Nocturno冒頭の発言は少し誤解を招くと思います。There's nothing stopping malicious code from spoofing the origin->はい、JavaScriptは設定できませんOrigin。はい、ユーザーはブラウザを変更したり、フィドラーを使用してオリジンを変更したりできますが、それはCORSが防御していることではありません。攻撃者が制御するWebサイトはOriginを変更できません。
RJFalconer

12

控えめにまとめます。

Q:同一生成元ポリシー(SOP)はブラウザーによってのみ強制されますか?
A:はい。ブラウザ内で行うすべての呼び出しについて、SOPは確実にブラウザによって適用されます。サーバーは、要求の発信元をチェックする場合としない場合があります。

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

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

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

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


ニース、より良い/ IMO受け入れ答えより明確に
3dGrabber
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.