JWTの保存先はどこが良いの?
#jwt #認証 #セキュリティ
JWTとは何か、JWTの基本的な認証の仕組みを理解したところで、いくつか難しい議論に直面する。
「JWTをクライアントサイドのどこに置いとくの問題」はその1つ。
1つの正解というのは無くて、セキュリティ要件・開発工数などの軸から最適な保存先を選択すべし。
ここでは、保存先の候補をいくつか出して、それらの特徴・メリデメを比較していきたい。
先に簡単な候補一覧から
1. Local Storage
2. Cookie
3. in-memory(グローバル変数)
結論.icon セキュリティ強度を少しでも上げたいならCookie、開発工数を小さくしたいならLocal Storage
XSSの前だと、究極どちらも無力ではある。
ただ、Local Storageは、無差別攻撃でもやられてしまう。なので、無差別にやられないように注意したいならCookieに保存するといい。
無差別攻撃の例:公式っぽいライブラリに不正コードを含ませておく
ライブラリにLocalStorage.getとかいうコードを入れたりして、無差別に多くのサイトから盗んでくる輩に簡単にも盗まれる
とはいえ、Cookieに保存してても、特定的に攻撃されると結局はやられる。サイトに脆弱性がある上で、攻撃者が念入りな調査したら終わり。
参考:
認証用トークン保存先の第4選択肢としての「Auth0」 - ログミーTech
【PoC編】XSSへの耐性においてブラウザのメモリ空間方式はLocal Storage方式より安全か? - Flatt Security Blog
SPAセキュリティ入門~PHP Conference Japan 2021
Reactでの認証時にJWTをCookieに設定する方法
切り取り線.icon
Local Storageに保存する場合
XSSが発生した場合、何のコストもなく情報を盗まれるリスクあり。
Cookie(Http Only)だと、こんなことは起こらない。
開発工数は比較的低いはず。
LocalStorageに置いておくだけ、必要になったらgetするだけ。
システムアーキテクチャの制約上、Cookieが使えない場合に有効
in-memoryに保存する場合
XSSが発生した場合、ここも普通にトークンを盗まれるリスクがある。
開発工数はもちろん低い。
Cookie
HttpOnly属性を付与すれば、JavaScriptから情報を奪取されるリスクが低くなる。
少なくとも他の選択肢よりは、攻撃コストが低くなることは確か。
とはいえ、特定サイトを狙ったXSSなら、普通に悪用されるので注意。
特定サイトを狙うパターンと広範囲を狙うパターンでは攻撃が違う。
広範囲パターンは、色んなサイトからあわよくば、機密情報を奪取できることを狙ってる。
特定パターンは、そのサイト(ex: yahoo.com, google.com...)を意図的に攻撃することを狙ってる。