JWTのaud(受信者)クレーム
JWT aud(受信者)クレームの仕組み、意図された受信者へのトークン使用制限方法、単一・複数受信者トークン、検証戦略について解説します。
詳細な説明
aud(受信者)クレームは、JWTの意図された受信者を識別します。トークンは、自身を意図された受信者として認識するサービスのみが受け入れるべきです。値は単一の文字列または文字列の配列で、それぞれが受信者識別子(通常はURIまたはサービス名)を表します。
単一受信者と複数受信者:
// 単一受信者
{ "aud": "https://api.example.com" }
// 複数受信者
{ "aud": ["https://api.example.com", "https://admin.example.com"] }
サーバーがJWTを検証する際、自身の識別子がaudクレームに含まれているかチェックします。含まれていない場合、トークンは拒否されます。これにより、一つのサービス向けのトークンが別のサービスに対してリプレイされることを防ぎます。両方のサービスが同じ署名鍵を共有するか、同じ発行者を信頼している場合でも同様です。
confused deputy問題:
受信者検証がなければ、confused deputy攻撃に対して脆弱になります。パブリックAPIと内部管理APIの2つのサービスがあり、両方が同じIDプロバイダーを信頼しているとします。攻撃者がパブリックAPI向けのトークンを取得し、管理APIに送信します。管理APIがaudをチェックしなければ、トークンの署名が有効なためアクセスが許可されてしまいます。受信者検証により、各サービスは自身に明示的に宛てられたトークンのみを受け入れることが保証されます。
OAuth 2.0と受信者:
OAuth 2.0フローでは、audクレームは通常、アクセストークンが意図されたリソースサーバー(API)を識別します。クライアントは認可フロー中にresourceまたはaudienceパラメータを使用して特定の受信者を要求します。例えばAuth0では、API識別子を受信者の値として使用します。これにより、一つのAPI向けに付与されたトークンが、同じ組織内であっても別のAPIで使用されることを防ぎます。
検証の実装:
受信者検証を実装する際は、audクレームに対して期待される受信者を完全文字列マッチングで比較してください。audが配列の場合、自サービスの識別子が配列に含まれているか確認してください。開発環境であっても受信者検証を省略しないでください。それが本番環境の脆弱性につながる習慣を作り出します。ほとんどのJWTライブラリは、検証時に期待される受信者の設定をサポートしています。
ユースケース
決済処理APIが、audクレームが自身のサービス識別子と一致するかを検証し、他のAPI向けに発行されたトークンによるトランザクションの認可を防ぎます。