目的
JWTの保存場所について情報が錯綜しているため、どのようにして保存場所を選択すべきであるかを考えたい。
JWTはlocalStorageに保存してはならない??
「JWTトークンは秘密情報を含むため、JavaScriptからアクセスできない場所に保存すべきである」といった主張があるがそれは、正しいのだろうか
また実際に社内において、XSS対策でHttpOnlyでSecureなCookieに格納してくれと言われたこともあった。
秘密情報をJavaScriptでアクセスできる場所に置くことに関して不安を覚えてしまうことは理解できるのですが、XSSを理由とすると話は違ってくる。
XSSに対するHttpOnlyの効果は限定的で、ほとんど無力である
もしXSS攻撃に対して脆弱性が存在している場合に攻撃を受けたことを考えてみる
以下にサンプルの脆弱性を載せたnextアプリが存在するため、適当に動かすと実感がわきやすいかもしれない
要は、JavaScriptでアクセスできないはずのCookieにある情報が、取得できてしまっていることが分かれば問題がない。
今回の手法は、ブラウザのほうにCookieを含めて外部のサーバーにPOSTしろとJavaScriptで設定しているだけである。XSSを仕掛ける場合にHttpOnlyによるJavaScriptのアクセス制限はこの程度しか効果がないのである。
XSSを理由にしてlocalstrageに保存してはいけないというのはあまりにも短慮である。
つまり、耐XSS性は理由とならない。
ほか参考サイト
あくまでもXSS対策において保険的対策に記述されていることに注意したい
localStorage や in-memory グローバル の方式は広範囲を狙う攻撃に弱い
in-memory ワーカー や Cookie の方式は広範囲を狙う攻撃に強い
うまくXSSに対するリスクを言語化してあります。このようなリスクもあることはある程度許容する必要があります。
必読です。
@ockeghem 先生のSPAのセキュリティに関する説明があります。
特にAPI認証等に関しても詳しい説明があるのでSPAを作成する場合は必ず読むべきスライドになります。
結局どこに保存すべきか
ここの考えと一致しているのですが、基本的に状況に合わせて考えるのが良いと考えています。
ここで注意が必要な点としては、cookieにJWTを設定する場合はCSRF攻撃の可能性が生まれることです。また、cookie容量の圧迫が起きるなどいろいろと問題もあります。
いろいろと考える必要はありますが、ステートフルにする必要がないのであればlocalstrageでよいのかなと個人的には考えています。
何かこの利用法ではcookie/localstrageのほうが良いということがある場合は、ご連絡ください!!
まとめ
JWTを考える中で、XSSやCORSについて改めて学ぶことができた。
また徳丸先生のスライドを見つけることができたのは僥倖である。