web-dev-qa-db-ja.com

Same-OriginポリシーだけではCSRF攻撃を防ぐことができないのはなぜですか?

まず、入力を制御してXSSの脆弱性を防ぐバックエンドを想定しています。

この回答 @Les Hazlewoodでは、クライアント側でJWTを保護する方法を説明しています。

ログイン中およびログイン後のすべての通信で100%TLSを想定します-基本認証を介してユーザー名/パスワードで認証し、代わりにJWTを受信することは有効なユースケースです。これは、OAuth 2のフロー( 'password grant')のいずれかが機能する方法とほぼ同じです。[...]

Authorizationヘッダーを設定するだけです:

Authorization: Bearer <JWT value here>

しかし、あなたのRESTクライアントが「信頼できない」(JavaScript対応ブラウザなど)である場合、私はそれもしません:JavaScriptを介してアクセス可能なHTTP応答の値-基本的には任意のヘッダー値または応答本体値-MITM XSS攻撃を介して盗聴および傍受される可能性があります。

JWT値をセキュア専用のHTTP専用Cookie(cookie config:setSecure(true)、setHttpOnly(true))に保存することをお勧めします。これにより、ブラウザは次のことを保証します。

  1. tLS接続でのみCookieを送信し、
  2. cookieの値をJavaScriptコードで使用可能にしないでください。

このアプローチは、ベストプラクティスのセキュリティを実現するために必要なほぼすべてのことです。 最後のことは、サイトへのリクエストを開始する外部ドメインが機能しないことを保証するために、すべてのHTTPリクエストでCSRF保護を確保することです

これを行う最も簡単な方法は、安全な(ただしHTTPのみではない)Cookieをランダムな値で設定することです。 UUID。

サイトへのリクエストを開始する外部ドメインが機能しないことを保証するために、ランダムな値のCookieが必要な理由がわかりません。これは、Same-Originポリシーでは無料ではありませんか?

[〜#〜] owasp [〜#〜] から:

Originヘッダーの確認

Origin HTTPヘッダー標準は、CSRFおよびその他のクロスドメイン攻撃から防御する方法として導入されました。リファラーとは異なり、OriginはHTTPS URLから発信されるHTTP要求に存在します。

Originヘッダーが存在する場合は、一貫性を確認する必要があります。

OWASP自体からの一般的な推奨事項はSynchronizer Token Patternであることは知っていますが、以下に残っている脆弱性を確認することはできません。

  • TLS +安全なhttpOnly CookieのJWT + Same-Originポリシー+ XSS脆弱性なし。

UPDATE 1:same-Originポリシーは XMLHTTPRequest にのみ適用されるため、悪意のあるサイトはPOSTリクエストすると簡単にセキュリティが破られます。明示的なOriginヘッダーチェックが必要です。式は次のようになります。

  • TLS +安全なhttpOnly CookieのJWT +Origin Header check+ XSS脆弱性なし。
31
gabrielgiussi

概要

私は、@ Bergi、@ Neil McGuigan、@ SilverlightFoxが明らかにするのを助けてくれたSame-OriginポリシーとCORSについての誤解された概念を持っていました。

まず第一に、@ Bergiが言うこと

SOPはリクエストの送信を妨げません。ページがクロスドメインリクエストの結果にアクセスすることを防ぎます。

重要な概念です。 SOPの制限に応じてブラウザがクロスドメインにリクエストを行うことはないと思ったが、これはMonsur Hossainが「それほど単純でないリクエスト」と呼ぶものにのみ当てはまる- this 優れたチュートリアル。

クロスオリジンリクエストには2つの種類があります。

  • 簡単なリクエスト
  • 「それほど単純ではないリクエスト」(作成したばかりの用語)

単純なリクエストは、次の基準を満たすリクエストです。

  • HTTPメソッドは次のいずれかに一致します(大文字と小文字を区別します):
    • HEAD
    • GET
    • POST
  • HTTPヘッダーの一致(大文字と小文字を区別しない):
    • 受け入れる
    • Accept-Language
    • コンテンツ言語
    • 最終イベントID
    • Content-Type。ただし、値が次のいずれかである場合のみ:
      • application/x-www-form-urlencoded
      • multipart/form-data
      • テキスト/プレーン

したがって、POST Content Type application/x-www-form-urlencodedを使用すると、サーバーにヒットします(これはCSRFの脆弱性を意味します)が、ブラウザーはそのリクエストの結果にアクセスできません。 POST Content Type application/jsonは「それほど単純ではないリクエスト」であるため、ブラウザはこのような事前請求を行います

オプション/ endpoint HTTP/1.1
ホスト:https://server.com
接続:キープアライブ
Access-Control-Request-Method:POST
起源:https://evilsite.com
Access-Control-Request-Headers:content-type
同意:*/*
Accept-Encoding:gzip、deflate、sdch
Accept-Language:es-ES、es; q = 0.8

サーバーが次のように応答する場合:

Access-Control-Allow-Origin: http://trustedsite.com
Access-Control-Allow-Methods:GET、POST、PUT
Access-Control-Allow-Headers:content-type
Content-Type:text/html; charset = utf-8

ブラウザはリクエストをまったく行いません。

XMLHttpRequestはロードできません http://server.com/endpoint 。プリフライトリクエストへの応答がアクセス制御チェックに合格しません。「Access-Control-Allow-Origin」ヘッダーに無効な値「trustedsite.com」が含まれています。したがって、Origin 'evilsite.com'はアクセスを許可されません。

ニールは次のことを指摘したときにこれについて話していたと思います。

same-Originポリシーは、データの読み取りにのみ適用され、データの書き込みには適用されません。

ただし、Bergiに提案したOriginヘッダーの明示的な制御では、この問題に関しては十分だと思います。

ニールに対する私の答えに関しては、その答えが私のすべての質問に対するものであるという意味ではありませんでしたが、SOPについての別の重要な問題を思い出しました。 。

結論として、私は方程式

  • TLS +安全なhttpOnly CookieのJWT + Origin Header check + XSS脆弱性なし。

aPIがSilverlightFoxが言うような別のドメインにある場合、良い代替手段です。クライアントがクライアントと同じドメインにある場合、Originヘッダーを含まないリクエストで問題が発生します。再び corsチュートリアル から:

Originヘッダーの存在は、リクエストがクロスオリジンリクエストであることを必ずしも意味しません。すべてのクロスオリジンリクエストにはオリジンヘッダーが含まれますが、同じオリジンリクエストの中にもオリジンヘッダーを持つものがあります。たとえば、Firefoxは同一生成元リクエストにOriginヘッダーを含めません。ただし、ChromeおよびSafariは、同一生成元POST/PUT/DELETEリクエストに生成元ヘッダーを含めます(同一生成元GETリクエストには、生成元ヘッダーがありません)。

Silverlightが指摘した this out。

残る唯一のリスクは、クライアントが許可されたOriginに一致するようにOriginヘッダーをスプーフィングできることです。したがって、私が探していた答えは実際には this でした。

UPDATE:この投稿を見る人のために、JWTを使用してOriginヘッダーが必要かどうかについて doubts を持っています。

方程式は次のようになります。

  • TLS +セキュアCookieに格納されたJWT +要求ヘッダーのJWT + XSS脆弱性なし。

また、前の式にはhttpOnly Cookieがありますが、クライアントとサーバーが異なるドメイン(今日の多くのSPAアプリケーションなど)にある場合、Cookieはサーバーへの各リクエストで送信されないため、これは機能しません。そのため、Cookieに保存されているJWTトークンにアクセスし、ヘッダーで送信する必要があります。

14
gabrielgiussi

Same-OriginポリシーだけではCSRF攻撃を防ぐことができないのはなぜですか?

Same-Originポリシーはデータの読み取りにのみ適用され、書き込みには適用されないためです。

http://compromised.comが(ユーザーのブラウザから)このようなリクエストを行うことを避けたい:

POST https://example.com/transfer-funds
fromAccountId:1
toAccountId:666

正当なリクエストは次のようになります。

POST https://example.com/transfer-funds
fromAccountId: 1
toAccountId: 666
csrfToken: 249f3c20-649b-44de-9866-4ed72170d985

これを行うには、外部サイト、つまりHTMLフォーム値または応答ヘッダーで読み取れない値(CSRFトークン)を要求します。

Originヘッダーについては、古いブラウザーではサポートされておらず、Flashにはクライアントが変更できる脆弱性がいくつかありました。基本的に、アドビが将来何も台無しにしないことを信頼するでしょう...それは良いアイデアのように聞こえますか?

すべてのHTTP要求でCSRF保護があることを確認します

状態の変更やメッセージの送信などの副作用のある要求に対してのみCSRF保護が必要です。

12
Neil McGuigan

答えをまとめたいだけです。

  1. 他にも述べたように、SOPはXmlHttpRequestsにのみ適用されます。つまり、仕様により、ブラウザーはOriginヘッダーをXmlHttpRequestsによって行われた要求とともに送信する必要があります。
  2. Chromiumをチェックすると、フォームを送信するときにOriginを送信します。ただし、これは他のブラウザーが行うことを意味するものではありません。以下の画像は、Firefoxで行われた2つの投稿リクエストを示しています。 1つは submitting フォームで、もう1つは [〜#〜] xhr [〜#〜] を使用して作成されます。両方のリクエストはhttp://hack:3002/changePasswordからhttp://bank:3001/chanePassword
  3. 同じドメインからリクエストが行われた場合、ブラウザーはOriginヘッダーを送信できません。したがって、サーバーは、Originヘッダーが設定されている場合にのみ、Originポリシーを確認する必要があります。

結論は次のとおりです。Cookieを使用し、リクエストがOriginヘッダーなしでサーバーに届いた場合、別のドメインからフォームを送信したのか、同じドメイン内のXHRで作成したのかを区別できません。そのため、CSRFで追加のチェックが必要です。

enter image description here

1
deathangel908