跳到主要内容

BFF パターンとトークン保護のセキュリティモデル

概要

BFF (Backend for Frontend) は、SPA(シングルページアプリケーション)専用のサーバー側レイヤーを 置き、認証とトークン管理をサーバー側に集約する設計パターンです。ブラウザにアクセストークンや リフレッシュトークンを一切渡さないため、XSS によるトークン窃取という SPA 最大の弱点を構造的に解消します。

OAuth 2.0 Security Best Current Practice(RFC 9700)および IETF の "OAuth 2.0 for Browser-Based Applications" は、高いセキュリティを要するブラウザアプリに対して この BFF パターンを推奨しています。

関連ドキュメント

本ドキュメントは BFF のセキュリティ上の動機と脅威モデルを扱います。.NET / YARP を使った具体的な 実装手順は BFF パターン with YARP、 UI アセットのホスティング戦略は BFF UIホスティング戦略 を参照してください。

なぜ BFF か:ブラウザにトークンを置くリスク

従来の SPA は、Authorization Code + PKCE フローでトークンを取得し、localStoragesessionStorage、あるいはメモリに保持して Authorization: Bearer ヘッダで API を呼び出します。 この方式には以下のリスクがあります。

リスク説明
XSS によるトークン窃取localStorage のトークンは、注入された任意の JavaScript から localStorage.getItem() で読み取れる
トークンの露出ブラウザの DevTools(Network / Application タブ)でトークンが見える
リフレッシュトークンのブラウザ保管長命なリフレッシュトークンがブラウザ上にあると、流出時の被害が大きい
クライアントシークレット不在SPA は秘密を安全に保持できず、PKCE のみに依存する

BFF はトークンをサーバー側にだけ置くことで、これらをまとめて排除します。

パブリッククライアント vs コンフィデンシャルクライアント

OAuth 2.0 のクライアントは、クライアントシークレットを安全に保持できるかどうかで2種類に分かれます。

  • パブリッククライアント:シークレットを安全に保持できない。SPA・ネイティブモバイルアプリが該当。 認可コード横取り対策として PKCE が必須。
  • コンフィデンシャルクライアント:シークレットを安全に保持できる。サーバー側アプリが該当。

BFF を導入すると、ブラウザアプリは「パブリッククライアント」から、サーバー側で動く コンフィデンシャルクライアントへと変わります。これによりクライアントシークレットによる強固な クライアント認証(PKCE との多層防御)が可能になります。

BFF の構成

BFF が担う責務は次のとおりです。

  1. 同一オリジン配信:SPA の静的ファイルと API プロキシを同一オリジンで提供(CORS 不要)。
  2. OIDC 認証:コンフィデンシャルクライアントとして Authorization Code + PKCE フローをサーバー側で実行。
  3. Cookie / セッション管理:ブラウザには HttpOnlySecureSameSite クッキー(中身は不透明な セッション参照のみ)を発行。トークン本体はサーバー側ストアに保管。
  4. CSRF 保護:Cookie 認証は CSRF 対策が必須(CSRF・SameSite・CSP 参照)。
  5. リバースプロキシ:API への転送時に Cookie を Bearer トークンへ変換し、トークンの期限確認・ 自動リフレッシュ・ローテーションを行う。

脅威モデル:BFF が防ぐもの・防がないもの

BFF の効果を正しく理解するうえで、最も重要なのが「トークン窃取」と「セッションライディング」の区別です。

脅威BFF の効果
XSS によるトークン窃取(持ち出し)✅ 防げる。トークンはブラウザに存在せず、HttpOnly クッキーは JS から読めない
トークンのネットワーク露出✅ 防げる。トークンはサーバー側にのみ存在
API の外部公開✅ 縮小できる。API を内部限定にし、BFF 経由に一本化
XSS によるセッションライディング⚠️ 防げない。クッキーは自動送信されるため、注入スクリプトは BFF 経由で認証済み API を呼べる
BFF は XSS 対策の代替ではない

BFF は脅威を「トークン窃取」から「セッションライディング」へ移すだけです。XSS が成立すれば、攻撃者は トークンを盗めなくても、被害者のセッションで API を操作できます。したがって、厳格な CSP(Content Security Policy) と XSS の根本対策は引き続き必須です。

標準・ベストプラクティスとの対応

  • RFC 9700(OAuth 2.0 Security BCP):機密性の高いブラウザアプリに BFF を推奨。
  • IETF "OAuth 2.0 for Browser-Based Applications":トークンをブラウザに置かない構成を推奨。
  • 「トークンはサーバー側に保持する」:これはトークン拘束(DPoP / mTLS) を不要にする最も簡単な方法でもあります。サーバー側保持なら盗まれるトークンがそもそも存在しません。

まとめ

  • BFF は SPA のトークン管理をサーバー側に集約し、XSS によるトークン窃取を構造的に排除する。
  • ブラウザアプリをコンフィデンシャルクライアント化し、クッキー(不透明なセッション参照)+ CSRF 保護で 認証する。
  • BFF が防ぐのはトークン窃取であり、セッションライディングは防げない → CSP と XSS 対策は必須。
  • 実装の詳細は YARP ベースの BFF 実装ドキュメントを参照。

関連ドキュメント

参考リンク