JWTセキュリティのベストプラクティス
JWTセキュリティの必須ベストプラクティスを解説。アルゴリズム選択、トークン保存、有効期間管理、クレーム検証、一般的な脆弱性の防止策を網羅します。
詳細な説明
JWTベースの認証を安全にするには、トークンの作成、送信、保存、検証の複数のレイヤーに注意を払う必要があります。単一の設定ミスが認証システム全体を危殆化させる可能性があります。すべての実装が従うべき重要なベストプラクティスを紹介します。
常にアルゴリズムを検証する:
algヘッダーは、検証に使用するアルゴリズムをサーバーに指示します。攻撃者はalgを「none」に変更して署名検証を無効にしたり、RS256からHS256に切り替えて公開鍵をHMACの秘密鍵として使用したりできます。JWTライブラリには受け入れるアルゴリズムの明示的なリストを常に設定し、トークンに検証方法を指定させないでください。
// 正しい: 許可するアルゴリズムを明示的に指定
jwt.verify(token, publicKey, { algorithms: ['RS256'] });
// 間違い: ライブラリにアルゴリズムを自動検出させる
jwt.verify(token, key);
適切なトークン有効期間を使用する:
アクセストークンは5〜15分で期限切れにすべきです。リフレッシュトークンはセキュリティ要件に応じて数時間〜数日で期限切れにすべきです。expクレームなしのトークンを決して発行しないでください。有効期間が短いほど、盗まれたトークンを悪用するウィンドウが小さくなります。
すべての関連クレームを検証する:
常に検証すべき項目: exp(期限切れトークンを拒否)、iss(信頼できない発行者からのトークンを拒否)、aud(自サービス向けでないトークンを拒否)、そして署名。これらのチェックのいずれかを省略すると、悪用可能な脆弱性が生まれます。多くのJWTライブラリはexpを自動的に検証しますが、明示的に設定しない限りissとaudはスキップします。
署名鍵を保護する:
HS256の場合、秘密鍵は少なくとも256ビットの暗号学的ランダム性が必要です。シークレットマネージャー(AWS Secrets Manager、HashiCorp Vaultなど)に保存し、ソースコードやバージョン管理にコミットされた環境ファイルには決して保存しないでください。RS256/ES256の場合、秘密鍵を同じ厳格さで保護してください。トークン発行者のみが秘密鍵にアクセスできるべきです。
トークンの安全な送信と保存:
常にHTTPSでトークンを送信してください。ブラウザでは、可能な場合はHttpOnly CookieにSecure属性とSameSite=Strict属性を付けてトークンを保存してください。localStorageを使用する場合は、XSSリスクを認識し、Content Security Policyヘッダーを実装してください。トークンをURLやクエリパラメータに含めないでください。これらはサーバーログ、ブラウザ履歴、Refererヘッダーに表示されます。
ユースケース
セキュリティチームがJWT監査を実施し、APIが「none」アルゴリズムを受け入れていることを発見し、RS256のみの検証を強制する修正を即座にデプロイします。