JWTはlocalStorageまたはcookieに保存する必要がありますか?[複製]


99

JWTを使用してRESTAPIを保護する目的で、いくつかの資料(このガイドやこの質問など)によると、JWTはlocalStorageまたはCookieのいずれかに保存できます。。私の理解に基づく:

  • ローカルストレージはXSSの対象であり、通常、機密情報を格納することはお勧めしません。
  • クッキー我々はXSSのリスクを軽減フラグ「のHttpOnly」を適用することができます。ただし、バックエンドのCookieからJWTを読み取る場合は、CSRFの対象になります。

したがって、上記の前提に基づいて、JWTをCookieに保存するのが最善です。サーバーへのすべてのリクエストで、JWTはCookieから読み取られ、ベアラースキームを使用してAuthorizationヘッダーに追加されます。サーバーは、(Cookieから読み取るのではなく)リクエストヘッダーのJWTを確認できます。

私の理解は正しいですか?もしそうなら、上記のアプローチにはセキュリティ上の懸念がありますか?それとも、実際には、そもそもlocalStorageの使用をやめることができますか?



@ lrn2prgrmは、(ステートレス)JWT(ステートフル)セッションセマンティクスを一緒に使用しないでください。
ozanmuyes

回答:


56

@ pkid169が述べた記事で言及されているXSRFダブルサブミットCookieメソッドが好きですが、記事で説明されていないことが1つあります。攻撃者が実行できるのは、CSRF Coo​​kie(HttpOnlyではない)を読み取るスクリプトを挿入し、このCSRFトークンを使用してAPIエンドポイントの1つにリクエストを送信し、JWT Cookieが自動的に送信されるため、XSSから保護されません。

したがって、実際にはまだXSSの影響を受けやすく、攻撃者が後で使用するためにJWTトークンを盗むことはできませんが、XSSを使用してユーザーに代わってリクエストを行うことはできます。

JWTをlocalStorageに保存する場合でも、XSRFトークンをhttpのみではないCookieに保存する場合でも、どちらもXSSで簡単に取得できます。HttpOnly Cookie内のJWTでさえ、高度なXSS攻撃によって取得される可能性があります。

したがって、Cookieの二重送信方法に加えて、コンテンツのエスケープを含め、XSSに対するベストプラクティスに常に従う必要があります。これは、ブラウザが望まないことを実行する原因となる実行可能コードを削除することを意味します。通常、これは、JavaScriptが評価される原因となる// <![CDATA [タグとHTML属性を削除することを意味します。


11
HttpOnly CookieのJWTを取得する方法を明確にできますか?XSRFトークンがXSSによって侵害された場合、XSRFによって使用できますが、実際にそれ自体を取得できますか?
ヤツェクゴルゴン

1
これが古い投稿であることは知っていますが、いくつか質問したいのですが...それは、巧妙に作成されたスクリプトがlocalStorageとcookieの両方を読み取ることができるということですか?もしそうなら、JWTをブラウザのどこに保存しても、JWTが盗まれる可能性があると想定しても安全ですか?そうすると、JWTだけに頼るのは非常に危険だと思います。
ヒロキ

2
「HttpOnlyCookie内のJWTでさえ、高度なXSS攻撃によって取得される可能性があります。」は誤りです。これを修正するために元の投稿を編集しました。
java-addict3 0119

「HttpOnlyCookie内のJWTでさえ、高度なXSS攻撃によって取得される可能性があります」誰かが自分のサーバーに送信することでCookieを取得することを想像できます。そのために、彼は資格情報フラグの適切な値でフェッチを使用できます。ここでの主な問題はCORS保護ですが、状況によっては可能だと思います。
bartnikiewi.cz

「CSRFCookie(HttpOnlyではない)を読み取るスクリプトを挿入する」Html.AntiForgeryToken()ASP.NET MVCのデフォルトの実装では、CSRFトークンにHttpOnlyCookieを使用します。あなたはまだ特定のXSSの影響を受けやすいと思いますが、これは言及する価値があると思いました。
Lovethenakedgun

21

Stormpathからのタイムリーな投稿、私のポイントをかなり詳しく説明し、私の質問に答えました。

TL; DR

JWTをCookieに保存してから、前述のようにすべてのリクエストでAuthorizationヘッダーにJWTを渡すか、記事が示唆しているように、バックエンドに依存してCSRFを防止します(xsrfTokenAngularの場合など)。


1
こんにちは、これが正しいかどうかはわかりませんが、コントローラーにCrossOriginを実装しているときに、Cookieを使用してjwtを保存することには、特定の欠点があります。これは、サーバーアプリが別の場所にあり、別の都市にある私たちのクライアントアプリでそれからのAPI?多くのWebサービスプロバイダーがCookieの使用を控えているのはそのためではありませんか?
valik

CrossOriginは物理的な場所を意味するものではありません。他のドメインからのリクエストを指します。.net Coreでは、CORSを使用する場合、許可するドメインを指定します。許可するヘッダーなど
Brian

11
  • トークンをLocalStorageまたはSessionStorageに保存しないでください。このようなトークンは、JavaScriptから読み取ることができるため、XSS攻撃に対して脆弱です。
  • トークンをCookieに保存しないでください。Cookie(HttpOnlyフラグ付き)の方が優れたオプションです。XSSが発生しやすいですが、CSRF攻撃に対して脆弱です。

代わりに、ログイン時に、アクセストークンと更新トークンの2つのトークンを配信できます。アクセストークンはJavascriptメモリに保存し、更新トークンはHttpOnlyCookieに保存する必要があります。更新トークンは、新しいアクセストークンを作成するためにのみ使用されます。これ以上は使用されません。

ユーザーが新しいタブを開いたとき、またはサイトの更新時に、Cookieに保存されている更新トークンに基づいて新しいアクセストークンを作成するリクエストを実行する必要があります。

また、この記事を読むことを強くお勧めします:https//hasura.io/blog/best-practices-of-using-jwt-with-graphql/


5
更新トークンをアクセストークンとして扱うことができるのに、なぜ複雑さが増すのですか?どのようにこのアプローチは、より多くの私は私のアクセスのようにトークンマーク与え確保されsecuresamesite: stricthttp-only
魅力的なロボット

それはより安全ではありません
クリスホークス

2

既存のCookieを利用するCSRF攻撃を防ぐために、SameSiteディレクティブを使用してCookieを設定できます。laxまたはに設定しstrictます。

これはまだドラフトであり、2019年現在現在のすべてのブラウザ完全にサポートされているわけではありませんが、データの機密性やユーザーが使用するブラウザの制御によっては、実行可能なオプションになる場合があります。でディレクティブを設定SameSite=laxすると、「 'safe' ... HTTPメソッドを使用するトップレベルのナビゲーション」が可能になります。

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