ブラウザでJWTを保存する場所は?CSRFから保護する方法は?


159

私はクッキーベースの認証を知っています。SSLおよびHttpOnlyフラグを適用して、Cookieベースの認証をMITMおよびXSSから保護できます。ただし、CSRFから保護するには、さらに特別な対策が必要になります。それらは少し複雑です。(参考

最近、JSON Web Token(JWT)が認証のソリューションとして非常にホットであることを発見しました。JWTのエンコード、デコード、および検証について知っています。ただし、JWTを使用している場合に、一部のWebサイト/チュートリアルでCSRF保護が不要であると説明されている理由がわかりません。私はかなりたくさん読んで、以下の問題を要約しようとします。私は、誰かがJWTの全体像を提供し、JWTについて誤解している概念を明確にしてほしいと思っています。

  1. JWTがCookieに格納されている場合、サーバーがCookie /トークンを検証するためのセッションを必要としないことを除いて、Cookieベースの認証と同じだと思います。特別な対策が講じられていない場合、CSRFには依然としてリスクがあります。JWTはCookieに保存されませんか?

  2. JWTがlocalStorage / sessionStorageに格納されている場合、Cookieがないため、CRSFから保護する必要はありません。問題は、JWTをサーバーに送信する方法です。ここで見つけたのは、jQueryを使用してajaxリクエストのHTTPヘッダーでJWTを送信することです。それで、ajaxリクエストだけが認証を行うことができますか?

  3. また、「Authorization header」と「Bearer」を使用してJWTを送信するブログショーがもう1つ見つかりました。私はブログが話している方法を理解していません。誰かが「Authorizationヘッダー」と「Bearer」についてもっと説明してもらえますか?これにより、JWTはすべてのリクエストのHTTPヘッダーによって送信されますか?はいの場合、CSRFはどうですか?

回答:


70

JWTトークンは、OAuth 2.0OpenID Connectなどの新しい承認および認証プロトコルでデフォルトのトークン形式として使用されるため、人気があります

トークンがCookieに保存されている場合、ブラウザは各リクエストと共に自動的にトークンを同じドメインに送信しますが、これはまだCSRF攻撃に対して脆弱です。

ベアラー認証は、HTTPで定義されている認証方式の 1つです。これは基本的にYOU、(JWT)トークンをリクエストのAuthorization HTTPヘッダーに貼り付けることを意味します。ブラウザーはNOTこれを自動的に実行するため、Webサイトの保護には適していません。ブラウザはヘッダーをリクエストに自動的に追加しないため、元のドメインに自動的に送信される認証情報に依存するCSRF攻撃に対して脆弱ではありません。

ベアラスキームは、AJAX呼び出しまたはモバイルクライアントから使用されるWeb API(RESTサービス)を保護するためによく使用されます。


1
@ Timespace7いいえ、JWTトークンもネイティブクライアントからよく使用されます。OAuth 2.0には、ネイティブ(モバイル)クライアントをターゲットにしたフローがあります。彼らが行わないことは、暗黙のブラウザー認証(Cookieや基本認証など)です。
MvdD 2014年

5
APIがAuthorizationヘッダーからJWTトークンのみを取得する場合、それはCSRFに対して脆弱ではないと言っています。Cookieからトークンを取得するサイトまたはAPIには、CSRF緩和策が必要です。
MvdD 2015年

13
これは、jwtをCookieに効果的に格納でき、Authorizationヘッダーでjwtを使用してリクエストを送信する場合に安全になることを意味しますか?
カメロンロー

10
@cameronjroe Cookieに保存できますが、認証にCookieを使用しない場合のみ(この場合はヘッダーを使用します)
Jaakko

1
AJAX呼び出しもブラウザーから発生します。JWTトークンは、主にWeb API(データの提供)の認証と、Webアプリ(マークアップ、画像、CSS、JavaScriptの提供)の認証に使用されるCookieの認証に使用されます
MvdD

143

JWTをクライアントコンピューターに保存する必要があります。LocalStorage / SessionStorageに保存すると、XSS攻撃によって簡単に取得される可能性があります。Cookieに保存すると、ハッカーはCSRF攻撃でそれを(読み取らずに)使用してユーザーになりすまし、APIに連絡して、アクションを実行したり、ユーザーに代わって情報を取得したりするためのリクエストを送信できます。

ただし、簡単に盗まれないようにCookieのJWTを保護する方法はいくつかあります(ただし、JWTを盗むための高度な手法はまだいくつかあります)。ただし、LocalStorage / SessionStorageに依存したい場合は、単純なXSS攻撃でアクセスできます。

CSRFの問題を解決するために、アプリケーションで二重送信Cookieを使用します。

Cookieの二重送信方法

  1. JWTをHttpOnly Cookieに保存し、それをセキュアモードで使用してHTTPS経由で転送します。

  2. ほとんどのCSRF攻撃では、リクエストの元のホストに異なる発信元ヘッダーまたはリファラーヘッダーがあります。ヘッダーにそれらが含まれているかどうかを確認してください。ドメインからのものかどうかを確認してください。そうでなければそれらを拒否します。オリジンとリファラーの両方がリクエストで利用できない場合、心配はありません。次のステップで説明するX-XSRF-TOKENヘッダー検証結果の結果を信頼できます。

  3. ブラウザーは要求のドメインに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属性を削除することを意味します。

詳細はこちら:


1
@AranDehkharghaniはいJWTを変更して、APIで使用されるたびに以前のJWTを期限切れにした場合は特に、リプレイ攻撃を防ぐことができると思います。これは、JWTがワンタイムパスワード(OTP)のようになることを意味します。JWTをさまざまな方法で使用できるかどうかは、プラットフォームのセキュリティをどの程度重視するかによって異なります。
Iman Sedighi 2016

7
おっしゃったように、WebサイトがXSSに対して脆弱である場合、ユーザーが悪用されるのは時間の問題です。セキュリティのごくわずかな増加に対して、かなりの複雑さを犠牲にしているようです。
shusson 2016年

3
@shusson JWTを保護するには、XSSおよびXSRF攻撃に注意する必要があります。セキュリティのごくわずかな増加に対して、かなりの複雑さを犠牲にしていることには同意しません。セキュリティが重要な場合は、XSSの脆弱性が発生しないようにあらゆる努力を払う必要があります。この方法は、XSRF攻撃からトークンを保護するように設計されています。ただし、XSSの脆弱性を無視できるという意味ではありません。
Iman Sedighi

5
@ImanSedighiわかりませんでした。jwtをcookieに保存すると、複雑さが増し、XSRFから保護する必要があります。では、なぜ短いライフトークンでローカルストレージを使用し、XSSの防止に集中しないのですか?
shusson

2
@Royi Namir:$ 10のSSL証明書を使用する場合、Wiresharkによるなりすましは問題になりません!Webサイトのセキュリティが重要な場合は、データを暗号化してHTTPSプロトコルを使用する必要があります。
Iman Sedighi 2017

2

JWTの保管に関する問題全体に対する別の角度:

  1. JWTをlocalStorageに保存しないでください
  2. 実際、非常に厳密なCSRF保護を実装できない限り、Cookie保存することはできません。

やる気のためにこれをチェックアウト

  • id_tokenとしてのJWTはユーザー資格情報のようなものです
  • access_tokenとしてのJWTはセッショントークンに似ています

最も安全なオプションはメモリ内です。詳細については、こちらをご覧ください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.