JWT認証、便利やん?

どうして JWT をセッションに使っちゃうわけ? - co3k.org に対して思うことを書く。

 

(ステートレスな) JWT をセッションに使うことは、セッション ID を用いる伝統的なセッション機構に比べて、あらゆるセキュリティ上のリスクを負うことになります。

 

と大口叩いておいて、それに続く理由がほとんどお粗末な運用によるものなのはどうなのか。最後に、

でもそこまでしてステートレスに JWT を使わなくてはいけないか?

 とまで行っていますが、JWT認証のメリットはその実装のシンプルさとステートレスなことにあります。現実的には実際はDB参照とか必要になったりするんですが、ほとんど改ざん検証だけで済むのは魅力的です。トレードオフでリアルタイムでユーザー無効化ができないことくらいですかね。ライブラリなんて使う必要ないほどシンプルだし、トレードオフさえ許容できればむしろ、なぜこれ以上に複雑な認証システム使わないといけないの?複雑さゆえにライブラリが必要になったり、そのライブラリが脆弱性を抱えていたり、そもそも使い方を間違えてしまったりするんでしょう。

ブコメでもありましたけど、FirebaseやAuth0でも対応している認証方法です。

 

Ruby on Rails のデフォルトのセッション管理機構 cookie store と同じ問題を抱える 

 について、セッションの無効化に難ありと以下のケースを出しておりますが。

  • ユーザのパスワード変更時、そのユーザーのアクティブなセッションをすべて無効にし、再ログインを促す

 アクティブなセッションを無効にする必要ないでしょう。そのために有効期限は短く設定してリフレッシュトークン使うようにするんだから。

  • ユーザのログイン履歴から、ユーザー自身の身に覚えのないセッションを選んで無効にする

トークンが盗まれば場合のことですよね?一時的にユーザーをロックして、リフレッシュトークン発行時、ロックされてるユーザーは発行できないようにすればいいでしょう。

  • パスワードリスト攻撃などによってアカウントが乗っ取られたユーザのセッションを無効化する

即時は無理ですね。ユーザーを無効化して有効期限が切れるのを待ちましょう。

 

ユーザの能動的な「ログアウト」はセッションを失効させない 

なにが問題なんだ?と思ったら次にこんなことが書いてありました。

ただし、何らかの要因でトークンを外部に晒してしまい、そのトークンによるセッションハイジャックを自主的に防ぐためのアクションとしてのログアウトは期待通りに機能しません。この場合、ユーザがログアウトをおこなってもセッションハイジャックは止められません。 

 さすがに乗っ取られてるような状況でログアウトすれば回避できると思う人はあまりいないとおもいますが・・・。

有効期限を明示的にペイロードに含まない限り、セッションが恒久的に有効になる 

 あたりめーだろ。

秘密鍵を知っていれば任意のユーザに対するセッションハイジャックが可能 

 秘密鍵の管理の問題ですね。JWTに限ったことではありません。

いわゆる退職者バックドアになる 

 また秘密鍵の管理の話ですね。なんで別項目にしたんだろ。

そもそも秘密鍵は定期的に更新しなければならない 

 また(ry。いやちょっと重要なこと言ってるな。以下に引用。

そうなるともちろん、定期的な鍵の更新を考慮しておく必要があります。一年に一回、元旦に全ユーザが一斉ログアウト&一斉ログイン、みたいなことをやるのはちょっとおもしろすぎる (「あけおめメール」ならぬ「あけおめログイン」ですね) ので、新旧鍵の併用期間が必要になってきます。そういう運用は想定していますか?

これはそう。見落としがちだけど、更新時期になってから実装しても遅くない。さすがに更新時期になったら、一斉ログアウトされちゃうことくらい気づくだろ。

JWT 特有の罠がある alg の柔軟性 (alg=none 許容で即死など) 

 ただの罠の話。どんな認証機構にも罠はある。JWTはシンプルなのでわざわざalgとか使ったライブラリとか使わなくてよし。

JWE で利用可能な暗号アルゴリズムが微妙 (らしい) 

 JWE使うケース、ほとんどないだろ。

トークンのサイズが大きくなる場合があり、 cookie にデータを保存しにくい 

 はい、localstorage

cookie の HttpOnly フラグの保護を受けない 

これは著者がおっしゃってるとおり、XSS脆弱性がある時点で論外。

まあチャレンジは大いに結構。大いに結構ですが、あえて危ない橋を渡るというのであれば、ここまで書き連ねたようなことくらいは一通り考え尽くしている必要があるかと思います。しかし実際のところ、考慮が不充分過ぎる実装にばかり出会うのは僕の運が悪いだけなのでしょうか。 

 あぁ、不運にも残念な実装に出会ってしまって起こってたのね。

でもそれでさ、JWT認証に使うなってのはどうなのよ。いっぱいセキュリティリスクあるように見せかけて、ほとんどがかなりポカしてるケースじゃん。

時代はパスワードレス認証とかもぼちぼち出始めてるのに。

これも仕組みも実装も超簡単。

Add Starknjnamehoppiekazu22002
  • 海老原昂輔 (id:co3k)

    ブコメが文字数制限で言葉足らずになっていそうなのでこちらでも。

    > いっぱいセキュリティリスクあるように見せかけて、ほとんどがかなりポカしてるケース

    そのとおりですが、見せかけて、というか、ポカして問題になるような実装になるということはつまりセキュリティリスクがあるってことですよね? auth0 さんはおそらく適切なリスク対応をおこなっておられるからそれで問題はないのでしょう。

    もちろん、古典的なセッション管理機構にもセキュリティリスクはあります。直接的なところだとセッション ID を類推可能だとマズいよ、とか、間接的なところだと (これは HTTP のせいですが) CSRF になるよ、とか。そしてそれに対応する方法が考えられ、議論され、提案されています。

    JWT によるセッション管理はそういった議論や安全なデファクトスタンダードとなるやり方が確立されているようには思えません。つまり自分でリスク特定などができない開発者が、古典的なセッション管理機構に比べて相対的に、安易に危険な実装を作り込んでしまいやすい状況にある。それを解決策の方針の提案も込みで、個別具体的に問題提起することはなにか間違っていますか?

    > JWT 認証に使うなってのはどうなのよ

    言っていません。僕はリスクの話しかしていません。リスクをコントロールしてメリットを享受できるならそうすればよいじゃないですか。しかし熟考してほしいと言っています。それは、(これについては間接的にしか書いていませんでしたが)古典的なセッション管理機構では長い年月を経てノウハウや仕組みが構築された結果、そのリスクコントロールをある程度ショートカットできるが、 JWT ではまだできないからです。

    たとえば、

    >> 有効期限を明示的にペイロードに含まない限り、セッションが恒久的に有効になる
    >
    > あたりめーだろ。

    と述べておられますが、そりゃもちろんあたりめーで、僕も実装に出会ったときにびっくりしましたが、こういうあたりめーな穴を作ってしまう人がいるわけです、現状だと。だからあたりめーなことでも言わないといけないのです。残念ながら。

    といったところで、元エントリの趣旨は伝わったでしょうか……?

  • 海老原昂輔 (id:co3k)

    あー、さらに補足ですが(すみません)、

    > いっぱいセキュリティリスクあるように見せかけて、ほとんどがかなりポカしてるケース

    なんですけど、そのほとんどが現実に遭遇した問題のある実装に基づいて述べています。というようなことも書いているはずですが、それは受け止めてもらえないのでしょうか。