背景から始めるために、 この投稿 は、Jeff AtwoodがCSRFトークンについて言っていることです。このページで、彼は続けて言っています:
さらに強力ですが、より複雑な防止方法は、サーバーの状態を利用することです。つまり、クライアントに送信するすべてのHTMLフォームに対して一意のランダムキーを生成(およびタイムアウト付きで追跡)します。 Stack Overflowでこのメソッドのバリアントを使用して、大きな成功を収めています。
しかし、この投稿自体では、Jeffはトークンをいつ、どのように更新する必要があるかについて決してコメントしていません。
私が取り組んでいるWebアプリで同様の手法を使用していました。それはこのように動作します:
POST
送信するたびに、csrfトークンが送信されます。POST
リクエストの後でトークンを更新するのは賢明ですか、それともユーザーがGET
リクエストを行って次のGETリクエストが行われるまで同じトークンを保持する場合にのみ更新を行う必要がありますか?
CSRFトークンの要点は、別のサイトから送信されていないということです。したがって、(a)攻撃者が予測または検出することはできず、(b)Cookieのようにリクエストに自動的に添付されることはありません。
したがって、理論的には、CSRFトークンが第三者に開示されない場合、理論的には、期限切れにする必要はまったくありません。しかし、どういうわけか、トークンが「漏洩」するリスクがあります。そのため、有効期限は、トークンが取得されてユーザーに対して使用される可能性に対抗するのに十分なほど短い必要があります。
実際にはガイドラインはありませんが、署名付きのタイムコードを埋め込むすべてのリクエストで新しいトークンを自動生成し、特定の年齢までのトークンを受け入れることをお勧めします。
関数の例は次のとおりです。
concat(current_time,salt,sha256_sum(concat(salt,userid,current_time,secret_string)))
トークンにはタイミング情報とソルトが含まれていますが、偽造できず、ユーザーIDに関連付けられている署名も含まれています。
次に、独自の有効期限を定義できます-1時間、1日、2時間。なんでも。この場合の間隔はトークンに関連付けられていないため、有効期限ルールは自由に設定できます。
ただし、少なくとも、CSRFトークンは、ログインセッションが期限切れになったとき、またはユーザーがログアウトしたときに期限切れになるはずです。ログアウトする前に表示したフォームが、再度ログインした後も引き続き機能することは、ユーザーには予期されていません。