MS_JWTSessionCookie - NetDevInfraWGinOSSConsortium/NetDevInfraWiki GitHub Wiki

JWTのコンテキストで何故かSessionとかCookieとか

概要

OAuth2/OIDCには結構詳しいつもりだケド、
出所が長々と解らなかった話が
「PHP Conference Japan 2021」で議論されていたので、まとめてみた。

詳細

Session 云々とかCookie 云々とか

移行メモ(アンカーの入れ違い): 元ページでは、概要の
「Session 云々」のリンクが Cookie 云々の節を、
「Cookie 云々」のリンクが Session 云々の節を指していた
(アンカー ID が入れ違っていた)。移行にあたって正しい節に対応付けた。

Session云々

  • これは、Session 情報をサーバに持たせるのではなく、
    Cookie に JWT として持たせるとステートレスに出来るよね?
    と言う主張が出所の話らしいが、どうも、認証機能も込で言及されているらしく、
    ログアウトをどうやって実装するのか?みたいな問題提起がされていたりする。

  • ...しかし、そんなことはしないのでパス。
    (Web サービスだとスケーラビリティを求められるのでやりたくなるらしい)

    • ステートフルで更新に強いものがステートレスで更新に弱くなる。
    • iat などを付与すれば、と言う話もあるが、スライディング有効期限に対応できない。

補足(JWT をセッションにすると何が困るか): 本節の要点は
JWT は発行後に取り消せない」ことに尽きる。

  • ログアウトしても、有効期限まではそのトークンが通ってしまう。
  • 権限を剥奪しても、次の再発行まで古い権限で通ってしまう。
  • 取り消しを実装しようとすると、結局サーバ側に失効リスト(jti)を持つことになり、
    ステートレスにした意味が薄れる。

「ステートフルで更新に強いものがステートレスで更新に弱くなる」という
著者の指摘はこのことを言っている。
実務ではアクセス トークンは短命(数分〜15 分)にして、
更新はリフレッシュ トークンで行う
ことで折り合いをつける。

Cookie云々

  • 安全に Token を取得しても、保存先の問題がある。
  • 話を聞いていると、どうも、Cookie vs LocalStorage と言う構図らしい。

Cookie

  • LocalStorage より安全という主張もあるがそんな事も無い感じ。

  • JWTに限らず、認証情報を Cookie に保存して API アクセスする場合の話。

  • XSSがアレば、Cookie は盗まれる可能性がある。

  • CORS の Access-Control-Allow-Credentials の設定に問題があると、
    CSRF(XSRF)的な攻撃が成立し易くなる(ただし、以下のハードルもある)。

    • POST で SameSite=None であること。
    • CSRF(XSRF)のチェックが実装されていないこと。

補足(HttpOnly なら XSS で盗まれない): 「XSS があれば Cookie は盗まれる」は、
HttpOnly を付けていない場合の話である。
HttpOnly を付ければ JavaScript から読めなくなるため、
document.cookie 経由での窃取は防げる。
ただし XSS があればその Cookie を使って攻撃者が API を叩ける
(盗まなくても悪用できる)ため、
「XSS があれば負け」という結論自体は変わらない。

LocalStorage

  • LocalStorage とは Web Storage の LocalStorageを指す。

  • コチラは、「Authorization: Bearer JWT」に限定された場合の話。

  • 危ないと言われているが、Cookieよりは安全と言う説が有力。

    • OAuth2/OIDCは、そもそも、CORS 用に考えられた仕組みで、

    • Origin が異なれば、対象の LocalStorage にアクセスできない。

    • SPA の XSS対策は必要になる。

補足(それぞれの弱点は別方向): 両者は「どちらが安全か」ではなく、
守れる脅威が違うと捉えるほうが正確である。

Cookie(HttpOnly) LocalStorage
XSS で直接読める 読めない 読める
XSS があれば悪用される される(自動送信されるため) される
CSRF 対象になる(自動送信されるため) 対象にならない
送信の制御 ブラウザ任せ(SameSite で緩和) コードで明示(Bearer ヘッダ)

現在の OAuth 2.0 for Browser-Based Apps
推奨は、そもそもブラウザにトークンを置かない(BFF でサーバ側に保持し、
ブラウザとは HttpOnly Cookie でやり取りする)という第 3 の選択肢である。

保存先問題の対策

  • セキュアと言われているモノには、SameSite が前提であるモノも多いので、
    CORS をする場合は、結局、アプリをセキュアにして行く必要がある。

  • Defence in Depth しても Weakest Link になるので、
    大差ない基盤の1層に注力しても全体としてセキュアにならない。

  • SPA の XSSのパターンを理解しておく必要がある。

ステート

ステートレスステートフル

ステートレス

JWTは、そもそもステートレス。

ステートフル

  • トークン管理を実装するために、ステートフル化するケースがある。

  • トークン無効化だけならステートレス(無効化するトークンの jti ダケを保持)に出来るが、
    発行済トークン一覧などを実装する場合、
    ステートフル(発行先と jti をサーバーに持たせるよう)にする必要がある。

OAuth 2.0 Token Revocation
OAuth 2.0 Token Introspectionを参照)

参考

Qiita

本 Wiki 内


Tags: IT国際標準, 認証基盤, クレームベース認証, OAuth

⚠️ **GitHub.com Fallback** ⚠️