web-dev-qa-db-ja.com

CSRF保護とシングルページアプリ

Angular.js(シングルページアプリ)を使用してシッククライアントWebアプリを作成している最中ですが、CSRFトークンを使用してアプリを保護するためのベストプラクティスは何なのかと思っていました。

アプリが最初に読み込まれたときにCSRFトークンを送信し、すべてのリクエストでそのトークンを再利用する必要がありますか?トークンを更新するメカニズムが必要ですか? 1ページのアプリにとってより意味のあるCSRFトークン以外の保護はありますか?

31
Olivier Lalonde

さて、これが私がCSRFを実装した方法です。

最初の要求で、CSRFトークンをcookieとして設定します。以降のすべてのAJAXリクエストには、CSRFトークンがX-CSRF-Token HTTPヘッダーとして含まれます。

Djangoには、jQueryでこれをきれいに行う方法に関する素晴らしいドキュメントがあります。 https://docs.djangoproject.com/en/dev/ref/contrib/csrf/

編集:代替アプローチは、X-Requested-Withヘッダーを含むリクエストをホワイトリストに登録します。 Railsが行うこと のようです。しかし、@ damioが以下で指摘しているように、X-Requested-Withはセキュリティ上の問題です Django and Rails reverted 使用しないでトークンを強制することに戻ります。

18
Olivier Lalonde

運がいい!ちょうど約2週間前に私は同じ質問をされました、そして少し頭を悩ませた後、私は次のことを思いつきました。これは十分に査読されていないため、コメントと投票がどのように行われるかを確認します。個人的にはいいテクニックだと思います。

1。最初のリクエスト

アプリケーションをロードする最初のリクエストを受け取ったら、安全なランダム識別子を生成してサーバーのセッション変数に格納し、それをクライアントに送信します。 _</body>_の直前のページに埋め込みます。

_<script>setToken('<% print SESSION[TOKEN] %>');</script>
</body>
_

setToken()は、トークンを保持する変数にトークン値を割り当てます。

2。後続のリクエスト

リクエストごとに、そのトークンを_token=TOKEN_などのパラメーターのリストに追加します。サーブは、トークンをセッション変数に格納されているトークンと照合します。

。トークンの更新

必須ではありませんが、トークンを時々、たとえば15分間更新することをお勧めします。トークンの有効期限が切れた後(セッション変数に有効期限がある場合)にリクエストを受け取ると、通常は(楽観的に動作して)応答しますが、その応答では、古いトークンの有効期限が切れたため、クライアントが新しいもの。

クライアントは、サーバーに新しいトークンを認識したことをサーバーに通知することでそれに対応します。サーバーがその要求を取得すると、新しいトークンの使用を開始し、OKメッセージでクライアントに応答します。クライアントが_200 OK_を受信すると、それは、両方が同期しており、クライアントは新しいトークンの使用を開始します。

注:プロセスの重要な要素はHTTPSの使用です。真ん中の男にトークンを盗聴させたくない。しかし、それでも、MitMはCookieを傍受してセッションをハイジャックすることができます。

16
Adi