POST
でフォームを送信する特定のアプリケーションのために、CSRFトークンが必要です。ストレージとDBのトラフィックとレイテンシを回避するために、送信ごとにDBを呼び出さないのが理想的です。このために OWASPの「CSRF防止に関するチートシート」 は、
概要
暗号化されたトークンパターンは、トークン検証の比較ではなく暗号化方式を利用します。認証が成功すると、サーバーは、サーバーでのみ使用可能な一意のキーを使用して、ユーザーのID、タイムスタンプ値、およびナンスで構成される一意のトークンを生成します。このトークンはクライアントに返され、非表示フィールドに埋め込まれます。 […] AJAX以外のフォームベースのリクエストは、非表示フィールドにトークンを暗黙的に永続化します。このリクエストを受信すると、サーバーはトークンの作成に使用されたのと同じキーでトークン値を読み取り、復号化します。 […]
検証
トークンの復号化が成功すると、サーバーは解析された値に、理想的にはクレームの形式でアクセスできます。
"Validation"の最初の行は、 [〜#〜] jwt [〜#〜] の定義のように、私には読みます。トークンの情報を暗号化する必要がある理由もわかりません。サーバーからの情報であることが認証されるだけでよいようです(攻撃者がCSRFトークンを偽造しようとしているのではありません)。
CSRFトークンを暗号化する特別な理由はありますか?そうでない場合、JWTで十分ですか?
また、上記のトークンパターンにはナンスが含まれています。 nonceのポイントは何ですか? (このパターンの要点は、サーバー側の状態を保存しないことです。状態を保存しない場合、検証中にナンスを重要な方法でどのように使用できますか?)
ここでJWTを追求する主な理由は、適切なライブラリサポートがあるためです。遅かれ早かれ、認証のためにそれらを使用したいと思うでしょう。それにより、暗号化の実装から遠ざけられます。
JWTについての私の理解は、完全なユーザー認証用のJWTがある場合、それらをlocalStorage
に格納し、フォーム送信の前にJSを使用してフィールドに単に追加できることです。残念ながら、このアプリはCookieベースの認証を使用しており、現在、そのアスペクトを変更することはできません。
トークンを暗号化したり、ナンスを含める必要はありません。 CSRFトークンの主要な特性は、攻撃者が予測できないこと、およびCookieとは異なり、ブラウザーによるすべての要求に追加されないことです。非表示のフィールドに保存された暗号的に安全な [〜#〜] jwt [〜#〜] は、これらのプロパティの両方を満たします。
ユーザー固有のデータが含まれているJWTを使用する必要があることに注意してください。ユーザー固有ではない空または汎用のJWTを使用しても、セキュリティは提供されません。
TL; DR
JWTをCookieなしで使用すると、CSRFトークンの必要性がなくなります-しかし! JWTをsession/localStorageに保存することにより、サイトにXSSの脆弱性がある場合(かなり一般的)にJWTとユーザーのIDを公開します。 csrfToken
キーをJWTに追加し、secure
およびhttp-only
属性が設定されたCookieにJWTを保存することをお勧めします。
詳細についてはこの記事をよく読んでください https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage
XsrfToken JWTクレームを含めることで、このCSRF保護をステートレスにすることができます。
{ "iss": "http://galaxies.com", "exp": 1300819380, "scopes": ["Explorer", "solar-harvester", "seller"], "sub": "[email protected]", "xsrfToken": "d9b9714c-7ac0-42e0-8696-2dae95dbc33e" }
したがって、csrfTokenをlocal/sessionStorageおよびにJWT(httpのみの安全なcookieに格納されている)に格納する必要があります。次に、csrf保護のために、JWTのcsrfトークンが送信されたcsrf-tokenヘッダーと一致することを確認します。
JWTをCSRFトークンとして使用することもできますが、それは不必要に複雑になります。CSRFトークンには、クレームを含めたり、暗号化したり、署名したりする必要はありません。
JWTトークンまたはCSRFトークンの用途について誤解があると思います(最初は混乱しました)。 JWTは、認証に使用されるアクセストークンです。一方、CSRFトークンは、ユーザーが騙されて偽造された認証済みリクエストを送信するのを防ぐために使用されます。これは、セッションまたはHTTP基本認証を使用する場合、またはJWTをCookieに保存する場合(ブラウザーによって自動的に実行されるすべての認証)に必要です。
このような認証スキームを使用している場合は、
たとえば、 SpringがCSRF を処理する方法を読んでください。