18

Django には、フォームで使用するための一意のセッションごとのトークンを生成するCSRF 保護ミドルウェアが付属しています。すべての受信POSTリクエストをスキャンして正しいトークンを探し、トークンが見つからないか無効な場合はリクエストを拒否します。

一部の POST リクエストに AJAX を使用したいのですが、リクエストには CSRF トークンがありません。ページには<form>フックする要素がなく、トークンを非表示の値として挿入してマークアップを混乱させたくありません。これを行う良い方法は/get-csrf-token/、ユーザーのトークンを返すようなビューを公開し、ブラウザーのクロスサイト スクリプティング ルールに依存して、敵意のあるサイトがトークンを要求するのを防ぐことだと考えています。

これは良い考えですか?AJAX リクエストを許可しながら、CSRF 攻撃から保護するためのより良い方法はありますか?

4

3 に答える 3

16

更新:以下は真実であり、すべてのブラウザとプラグインが適切に実装されていれば真実であるはずです。残念ながら、現在はそうではなく、ブラウザプラグインとリダイレクトの特定の組み合わせにより、攻撃者がクロスドメインリクエストで任意のヘッダーを提供できる可能性があることがわかりました。残念ながら、これは、「X-Requested-With:XMLHttpRequest」ヘッダーを持つAJAXリクエストでさえCSRFで保護されている必要があることを意味します。その結果、DjangoはAjaxリクエストをCSRF保護から免除しなくなりました。

元の回答

ブラウザはクロスサイトAJAXリクエストを許可しないため、CSRFからAJAXリクエストを保護する必要はありません。実際、Django CSRFミドルウェアは、CSRFトークンスキャンからAJAXリクエストを自動的に免除するようになりました。

これは、X-Requested-Withヘッダーサーバー側で「XMLHttpRequest」値(Djangoが行う)を実際にチェックし、実際のAJAXリクエストをCSRFスキャンから除外する場合にのみ有効です。

于 2009-02-10T17:55:11.613 に答える
14

AJAX 要求に CSRF トークンが必要になることがわかっている場合は、いつでも HTML のどこかに埋め込むことができます。次に、DOM をトラバースすることで Javascript を介して見つけることができます。この方法では、引き続きトークンにアクセスできますが、API 経由で公開することはありません。

別の言い方をすれば、URL ディスパッチャーではなく、Django のテンプレートを使用して実行します。この方法の方がはるかに安全です。

于 2008-09-28T01:36:36.050 に答える
1

それをキャンセルしてください、私は間違っていました。(コメントを参照してください。) JSON が仕様に従っていることを確認することで、エクスプロイトを防ぐことができます。常にオブジェクト リテラルを最上位オブジェクトとして返すようにしてください。(これ以上悪用されないという保証はできません。window.onerror イベントで失敗したコードへのアクセスを提供するブラウザーを想像してみてください!)

クロスサイト スクリプティング ルールに依存して、AJAX 応答をプライベートに保つことはできません。たとえば、CSRF トークンを JSON として返すと、悪意のあるサイトがString または Array コンストラクターを再定義し、リソースを要求する可能性があります。

bigmattyh は正しいです。トークンをマークアップのどこかに埋め込む必要があります。または、リファラーが一致しないPOST を拒否することもできます。そうすれば、熱狂的なソフトウェア ファイアウォールを使用している人だけが CSRF に対して脆弱になります。

于 2008-09-28T17:58:09.217 に答える