REST-apiの場合、CSRF攻撃から保護するには、カスタムヘッダーの存在を確認するだけで十分です。クライアントが送信する
「X-Requested-By:何でも」
サーバーは「X-Requested-By」の存在を確認し、ヘッダーが見つからない場合はリクエストをドロップします。ヘッダーの値は無関係です。これは、Jersey 1.9のCsrfProtectionFilterがどのように機能するかであり、このブログ投稿で説明されています: http://blog.alutam.com/2011/09/14/jersey-and-cross-site-request-forgery- csrf / 。ブログの投稿は、カスタムヘッダー自体で十分に保護できることを示すNSAおよびStanfordの論文にもリンクしています。
最初の方法では、X-XSRF-Headerなどの各RESTリクエストにカスタムヘッダーを設定します。このヘッダーの値は重要ではありません。単に存在することでCSRF攻撃を防ぐことができます。リクエストがカスタムヘッダーなしでRESTエンドポイントに到達した場合、リクエストはドロップされます。
フォーム、画像、iframeなどを介して実行されるWebブラウザーからのHTTP要求は、カスタムHTTPヘッダーを設定できません。ブラウザからカスタムHTTPヘッダーを使用してHTTPリクエストを作成する唯一の方法は、Javascript XMLHttpRequestやFlashなどのテクノロジーを使用することです。これらのテクノロジーはカスタムHTTPヘッダーを設定できますが、ポリシーで特に許可されていない限り、Webサイトが相互にリクエストを送信しないようにするためのセキュリティポリシーが組み込まれています。つまり、Webサイトwww.bad.comは、XMLHttpRequestなどのテクノロジを使用しない限り、カスタムヘッダーX-XSRFHeaderを使用してリクエストを http://bank.example.com に送信できません。そのテクノロジーは、bank.example.comドメインが明確に許可しない限り、そのようなリクエストが行われるのを防ぎます。これにより、XMLHttpRequest(または同様のテクノロジ)を介してのみ呼び出すことができるRESTエンドポイントが生成されます。
この方法は、WebブラウザーからそのRESTエンドポイントへの直接アクセスも防止することに注意することが重要です。このアプローチを使用するWebアプリケーションは、XMLHttpRequestまたは同様のテクノロジーを介してRESTエンドポイントとインターフェースする必要があります。
出典: REST実装のガイドライン
ただし、他のほとんどのアプローチでは、トークンを生成し、これをサーバーで検証する必要があることを示唆しているようです。これは過剰設計ですか? 「存在」のアプローチが安全になるのはいつですか。また、トークンの検証も必要になるのはいつですか。
セキュリティとは、徹底的に防御することです。現時点では値を確認するだけで十分です現時点では十分ですが、将来のテクノロジーや攻撃を利用して保護を破る可能性があります。トークンの存在をテストすることにより、現在の攻撃に対処するために必要な最小限の防御を実現します。ランダムトークンを追加すると、将来の攻撃ベクトルpotentialに対するセキュリティが向上します。リクエストごとのトークンを使用すると、攻撃者がリクエストごとに新しいトークンを盗む方法が必要になるため、XSSの脆弱性による被害を制限するのにも役立ちます。
これは、n
ラウンドが安全のための最小と見なされますが、2n+1
適切なセキュリティマージンを確保するために、公式実装では(たとえば)ラウンドが選択されています。
参考文献:
TL; DR-「X-Requested-By」などの非標準ヘッダーの存在を確認することで、ヘッダーの値を確認せずにCSRF攻撃を防ぐことができます。
Playフレームワークサイト 分解 本当にうまくいきます:
簡単に言えば、攻撃者は被害者のブラウザに次のタイプのリクエストを強制することができます。
- すべてのGETリクエスト
- タイプapplication/x-www-form-urlencoded、multipart/form-dataおよびtext/plainの本文を含むPOSTリクエスト
攻撃者は次のことを行えません:
- PUTやDELETEなどの他のリクエストメソッドを使用するようにブラウザーを強制する
- ブラウザーを強制して、application/jsonなどの他のコンテンツタイプを投稿する
- サーバーがすでに設定しているもの以外の新しいCookieを送信するようにブラウザを強制する
- ブラウザに要求に追加する通常のヘッダ以外の任意のヘッダを設定するようにブラウザを強制します
これは、CSRFの攻撃ベクトルを考慮すると理にかなっています。
JavaScriptは same-Originポリシー の対象であるため、次のいずれかの条件が満たされた場合にのみ、非標準ヘッダーを追加できます。
XSS攻撃では、非標準ヘッダーを設定できます。非標準ヘッダーを使用してCSRF攻撃を防止しても、ヘッダーの値に関係なく、サイトがXSS攻撃に対して脆弱になることはありません。非標準ヘッダーとCSRFトークンはどちらもXSS攻撃に対して脆弱です。 XSS攻撃者がリクエストに標準以外のヘッダーを設定できる場合(ドメイン内XHRなど)、Cookieに設定されているか、DOMまたはJavaScript変数に埋め込まれているCSRFトークンに確実にアクセスできます。
同様のSO質問 ここ がありますが、混乱を招きますが、同じ結論に達しました。
実際のそのような非標準ヘッダーのいくつかの例:
EDIT:このcsrf-request-builderはFlashの脆弱性を悪用していたが、現在は修正されている。 JavaScriptを使用して複雑なリクエストを送信することは可能です 追加のヘッダー要素を指定した場合、プリフライトOPTIONS HTTPリクエストが実際のリクエストの前に送信されます。
ジャージーはCSRFに対して脆弱であり、ジャージーの開発者に通知されていることを確認しました。 Flashおよび場合によっては他のスクリプト技術を使用して、この脆弱性を利用することが可能です。 「X-Requested-By」HTTPヘッダーが flash's header blacklist にないため、ジャージーは脆弱です。
CSRF-Request-Builder を次の引数と共に使用して、ポストリクエストを作成しました。
file://var/code/CSRF-Request-Builder/csrf_payload.html#url=http://google.com&X-Requested-By=1&body={'test':1}
CSRFの悪用について十分に理解していない限り、独自のCSRF防止方法を用意することはできません。 CSRF防止に関するチートシート は優れたリソースです。
https://stackoverflow.com/a/11423778/14731 は非常に重要なポイントになります。SameOrigin Policy(SOP)はreadingクロスドメインレスポンス。writingリクエストではありません。
つまり、将来的にカスタムヘッダーを記述できるようになる可能性がありますが、クロスドメインリクエストの応答を読み取ることができる可能性はほとんどありません。そのため、最良のCSRF保護には、サーバーからシークレット値を読み取り、それを書き戻し、サーバーに値を検証させることが含まれます。
これを達成するために必ずしもサーバー側の状態は必要ありません( Double-Submit Cookies 、および Encrypted Token Pattern はこの2つの例です)検証する必要がありますsomeサーバー上の秘密値。
2020年の時点で、MDNは「クロスオリジン書き込みを防ぐために、リクエスト内の推測不可能なトークンを確認する-クロスサイトリクエストフォージェリ(CSRF)トークンと呼ばれる」を明示的に推奨しています。 https://developer.mozilla.org/en-US/docs/Web/Security/Same-Origin_policy を参照してください(「クロスオリジンアクセスをブロックする方法」までスクロールします)。