JWTをクライアントコンピューターに保存する必要があります。LocalStorage / SessionStorageに保存すると、XSS攻撃によって簡単に取得される可能性があります。Cookieに保存すると、ハッカーはCSRF攻撃でそれを(読み取らずに)使用してユーザーになりすまし、APIに連絡して、アクションを実行したり、ユーザーに代わって情報を取得したりするためのリクエストを送信できます。
ただし、簡単に盗まれないようにCookieのJWTを保護する方法はいくつかあります(ただし、JWTを盗むための高度な手法はまだいくつかあります)。ただし、LocalStorage / SessionStorageに依存したい場合は、単純なXSS攻撃でアクセスできます。
CSRFの問題を解決するために、アプリケーションで二重送信Cookieを使用します。
Cookieの二重送信方法
JWTをHttpOnly Cookieに保存し、それをセキュアモードで使用してHTTPS経由で転送します。
ほとんどのCSRF攻撃では、リクエストの元のホストに異なる発信元ヘッダーまたはリファラーヘッダーがあります。ヘッダーにそれらが含まれているかどうかを確認してください。ドメインからのものかどうかを確認してください。そうでなければそれらを拒否します。オリジンとリファラーの両方がリクエストで利用できない場合、心配はありません。次のステップで説明するX-XSRF-TOKENヘッダー検証結果の結果を信頼できます。
ブラウザーは要求のドメインにCookieを自動的に提供しますが、1つの有用な制限があります。Webサイトで実行されているJavaScriptコードは他のWebサイトのCookieを読み取ることができません。これを活用してCSRFソリューションを作成できます。CSRF攻撃を防ぐには、XSRF-TOKENと呼ばれる追加のJavaScript読み取り可能なCookieを作成する必要があります。このCookieは、ユーザーのログイン時に作成する必要があり、推測不可能なランダムな文字列を含める必要があります。また、この番号をプライベートクレームとしてJWT自体に保存します。JavaScriptアプリケーションがリクエストを行うたびに、このトークンを読み取り、カスタムHTTPヘッダーで送信する必要があります。これらの操作(Cookieの読み取り、ヘッダーの設定)は、JavaScriptアプリケーションの同じドメインでのみ実行できるため、
Angular JSはあなたの人生を簡単にします
幸い、私はプラットフォームでAngular JSを使用しており、AngularはCSRFトークンアプローチをパッケージ化しているため、実装が簡単になっています。Angularアプリケーションがサーバーに対して行うすべてのリクエストに対して、Angular $http
サービスはこれらのことを自動的に行います:
- 現在のドメインでXSRF-TOKENという名前のCookieを探します。
- そのCookieが見つかると、値を読み取り、X-XSRF-TOKENヘッダーとしてリクエストに追加します。
したがって、クライアント側の実装は自動的に処理されます!XSRF-TOKEN
サーバー側の現在のドメインに名前が付けられたCookieを設定するだけで、APIがクライアントから呼び出しを受け取ったときに、X-XSRF-TOKEN
ヘッダーを確認XSRF-TOKEN
してJWTのと比較する必要があります。それらが一致する場合、ユーザーは本物です。それ以外の場合、それは偽造リクエストであり、無視できます。このメソッドは、「Double Submit Cookie」メソッドから着想を得ています。
注意
実際には、あなたはまだXSSの影響を受けやすく、攻撃者がJWTトークンを盗んで後で使用することはできませんが、XSSを使用してユーザーに代わって要求を出すことができます。
JWTをに格納するlocalStorage
場合も、XSRFトークンをHttpOnly Cookie以外に格納する場合も、どちらもXSSによって簡単に取得できます。HttpOnly Cookie内のJWTでさえ、XSTメソッドなどの高度なXSS攻撃によって取得される可能性があります。
したがって、Cookieの二重送信方法に加えて、コンテンツのエスケープなど、XSSに対するベストプラクティスに常に従う必要があります。これは、ブラウザに望まない動作をさせる実行可能コードを削除することを意味します。通常、これは// <![CDATA[
、JavaScriptが評価される原因となるタグとHTML属性を削除することを意味します。
詳細はこちら: