認証トークンの安全な取り扱いは、アプリケーションのセキュリティにとって極めて重要です。最適な手法は、アプリケーションの種類(Web、モバイル、サーバーサイド)や使用するトークンの種類(アクセストークン、リフレッシュトークン)によって異なります。
以下に、認証トークンを安全に取り扱うための一般的な原則とベストプラクティスを示します:
基本原則
- 秘密保持と安全確保: トークンは他の機密認証情報と同様に扱います。トークンの署名鍵は、それを必要とするサービスにのみ開示してください。
- HTTPSの採用: 傍受を防ぐため、トークンは常に安全なHTTPS接続で送信してください。
- ペイロード内の機密データを最小限に抑える: トークンは署名されていても容易に復号されるため、ペイロードにユーザーの機密データを含めないこと。
- 短い有効期限を設定する: アクセストークンの有効期限を短時間(数分から数時間)に設定し、トークンが侵害された場合の攻撃者の機会を制限する。
- ハードコーディングの回避: トークンをハードコードしたり、アプリケーション内に平文で保存したりしないでください。
アプリケーションタイプ別トークン保存方法
1. Webアプリケーション
- インメモリ保存(SPAにおけるアクセストークン用): アクセストークンをブラウザメモリに保存することは、ファイルシステム保存に伴うリスクを軽減するため安全な選択肢と見なされます。これはJavaScriptクロージャやWeb Workers(別個のグローバルスコープで実行)を使用して実現可能です。ただし、メモリに保存されたトークンはページ更新時やタブ閉じ時に失われます。
- セキュアなHttpOnly Cookie(リフレッシュトークンおよび従来型Webアプリ向け):
- リフレッシュトークンには、
SameSite属性(LaxまたはStrict)を指定したセキュアなHttpOnly Cookieを使用します。HttpOnly CookieはクライアントサイドJavaScriptからアクセスできないため、XSS攻撃ベクトルを低減します。 - 従来のサーバーサイドレンダリングWebアプリケーションでは、最大限のセキュリティのためトークンをサーバーに保存することを推奨します。クライアントサイドストレージが必要な場合は、暗号化されたセッションクッキーを使用してください。
- リフレッシュトークンには、
- ローカルストレージとセッションストレージの使用回避: 機密トークンを
localStorageやsessionStorageに保存しないでください。これらはクロスサイトスクリプティング(XSS)攻撃に対して脆弱です。
2. モバイルアプリケーション(iOSとAndroid)
- プラットフォーム固有のセキュアストレージ: オペレーティングシステムのセキュアストレージ機構を利用してください。
- iOS: キーチェーンを使用してください。
- Android: キーストアまたはAndroid内部データを使用してください。
- これらの機構は、機密データを保護し、デバイス上の他のアプリケーションからトークンを保護するように設計されています。
3. サーバーサイドアプリケーション
- サーバーサイドストレージ: バックエンドがAPI呼び出しを行うアプリケーションでは、トークンはサーバーに保存すべきです。これによりトークンがクライアントに公開されないため、最高レベルのセキュリティが提供されます。
- 暗号化されたストレージ: トークンを永続化する必要がある場合は、データベースまたはファイルシステム上で保存時に暗号化してください。
トークン管理のベストプラクティス
- リフレッシュトークン: リフレッシュトークンを使用して、ユーザーに頻繁な再認証を要求することなく、新しい短命のアクセストークンを取得します。 リフレッシュトークンは長寿命とし、安全に保存(例:HttpOnlyクッキー)し、使用後は理想的にローテーションする。
- トークンの失効: 侵害やユーザーログアウト時に、特にリフレッシュトークンを失効させる戦略を実装する。
- 最小限のクレーム: パフォーマンスとセキュリティのため、トークンペイロードには必要最小限のクレームのみを含める。
- クロックスキュー: 期限切れなどの時間ベースのクレームを検証する際、サーバー間のわずかな時間差を考慮し、数秒程度のクロックスキューを許容することを検討する。
- フロントエンド向けバックエンド(BFF)パターン: シングルページアプリケーション(SPA)では、バックエンドがトークンの取得と保存を処理し、SPAと認証サーバー間の安全な仲介役として機能するフロントエンド向けバックエンド(BFF)パターンの採用を検討する。