ペイロードと署名の間でJWTを分割する
コンテキスト:シングルページアプリケーションでのJWTトークンのストレージソリューションを検討しています。
- JWTをローカルストレージに保存することは安全ではなく、XSS攻撃を受けやすくなります。
- JWTを安全な/ HTTPのみのCookieに保存する方が安全ですが、CSRF攻撃を受けやすくなります。
私は次のシナリオを研究しています:
認証時に、更新トークンはhttpのみの安全なCookieに保存されます。アクセストークンを取得するためにのみ使用できます。
承認されると、バックエンドはJWTアクセストークンで応答します。JWTのヘッダーとペイロードの部分は、応答本文の内部にあります。トークンの署名は送信されず、httpのみの安全なCookieに設定されます(可能な場合は同じサイトで厳密ですが、そうではないと仮定します)。ヘッダー+ペイロードはメモリに保存されます。
JWTには次のクレームが含まれています
- iat、nbf、exp(推測可能なIMO)
- ユーザーIDとアクセス許可に関連するクレーム(ユーザーIDがわかっている場合は推測可能)
- jti、暗号的に安全な乱数を含む(私の場合、Pythonシークレットで生成されます)
リクエストを行う場合、ヘッダー+ペイロードは、承認ヘッダーでSPAによってXHR /フェッチを介して送信されます。署名はCookieと一緒に送信されます。バックエンドは両方を連結し、署名を検証します。
- このメカニズムはCSRF攻撃に対して安全ですか?jtiの主張は、認証トークンと署名Cookieを有効なCSRF緩和手法にしますか?
- このメカニズムは、ローカルストレージ内にJWTを保存するよりも、XSS攻撃に対して実際に安全ですか?(XSSを使用した攻撃も、TRACEエクスプロイトのように簡単にシグネチャを盗む可能性があります)。
注:私はこの質問を読みましたが、これは似ていますが、広すぎるため、より正確な回答を得るためにこれを投稿しています。
回答
このメカニズムはCSRF攻撃に対して安全ですか?
JWTを分割し、署名をCookieに保存し、トークンの残りをブラウザストレージに保存するこの方法では、JWT全体がローカルストレージまたはセッションストレージに保存されている場合よりも、CSRF攻撃に対する追加の保護は提供されません。はい、CSRF攻撃を軽減しますが、サーバー上でJWTを分割および連結するという不要なオーバーヘッドを追加する必要はありません。JWTをローカルストレージに保存し、Authorizationヘッダーでのみ受け入れるだけで、CSRF攻撃からアプリケーションを保護できます。
このメカニズムは、ローカルストレージ内にJWTを保存するよりも、XSS攻撃に対して実際に安全ですか?(XSSを使用した攻撃も、TRACEエクスプロイトのように、簡単にシグネチャを盗む可能性があります)
攻撃者がJWTを盗むことができることにのみ焦点を当てている場合、正しく述べたように、サーバーでTRACEが有効になっていない限り、このアプローチは安全です。
ただし、これによってアプリケーションがXSS攻撃から安全になるわけではありません。たとえば、アプリケーションで任意のJavascriptを実行できる場合、ローカルストレージからJWTヘッダーとペイロードをフェッチし、CredentialsをTrueに設定したままXHRを機密性の高いエンドポイントに送信できます。このエンドポイントは、たとえば、アカウントの電子メールアドレスを変更して設計されている場合があります。それはすぐにアカウントの乗っ取りにつながります。CookieやJWTを盗む必要はありません。
要約:このアプローチは、署名をトークンの残りの部分から分離することにより、セッショントークンに対するある程度の保護を提供します。ただし、XSSに関しては、セッショントークンを盗むことだけが注目すべきリスクではありません。