こんにちは。インフラ担当の森井康平です。
先日、ALBのJWT検証機能が発表されました。やや地味なアップデートなので何が嬉しいのか(メリット)を説明しようと思います。
ALB がJWTを検証してくれるようになったことで、JWT検証の実装をAWS管理で実現できるようになり、セキュリティを担保しやすくなったことが嬉しいポイントです。
OIDC認証機能の課題
JWT検証機能のアップデートを最初に見た時、まず既存のOIDC認証機能との違いが気になりました。JWT検証はOIDCにも内包されている処理のためです。
ALB には 2018 年より OIDC を用いた認証機能が提供されています。認証処理を ALB が担う便利な機能ですが、Cookie ベースの認証であるため、ブラウザを使用しないユースケース(API / サーバー間通信など)との相性が良くないという課題があります。
Application Load Balancer を使用してユーザーを認証する - Elastic Load Balancing
OIDC認証機能は下記の流れで処理を行います。

(引用元:Application Load Balancer を使用してユーザーを認証する - Elastic Load Balancing)
1.ユーザーは、Application Load Balancerの背後にホストされているウェブサイトにHTTPS リクエストを送します。認証アクションを持つルールの条件が満たされている場合、ロードバランサーはリクエストヘッダーに認証セッションCookie があるかどうかを確認します。
2. Cookie が存在しない場合、ロードバランサーはユーザーをIdP認可エンドポイントにリダイレクトし、IdPでユーザーを認証できるようにします。
3.ユーザーが認証されると、IdP は認可付与コードを伴ったユーザーをロードバランサーにリダイレクトして戻します。
4.ロードバランサーは認可付与コードをIdPトークンエンドポイントに示します。
5. 有効な認可付与コードを受け取ると、IdPはID トークンとアクセストークンをApplication Load Balancer に提供します。
6. 次に、Application Load Balancer がアクセストークンをユーザー情報エンドポイントに送します。
7. ユーザー情報エンドポイントは、ユーザーの要求に対してアクセストークンを交換します。 8. Application Load Balancer は、AWSELB 認証セッション cookie を持つユーザーを元のURIにリダイレクトします。ほとんどのブラウザでは Cookieのサイズを 4Kに制限しているため、ロードバランサーはサイズが 4Kを超える Cookieを複数の Cookieに分割します。IdP から受け取ったユーザークレームとアクセストークンの合計サイズが 11Kバイトを超える場合、ロードバランサーは HTTP 500 エラーをクライアントに返し、ELBAuthUserClaimsSizeExceededメトリクスを増分します。
9. Application Load Balancer は Cookie を検証し、ユーザー情報をX-AMZN-OIDC-*HTTP ヘッダー設定のターゲットに転送します。詳細については、「ユーザークレームのエンコードと署名の検証」を参照してください。
10. ターゲットは応答をApplication Load Balancer に戻します。
11. Application Load Balancer は、最終応答をユーザーに送します。
認証に成功した場合、ALBは新しいJWTを作成しターゲットに渡します。そのため、ターゲットはJWTを検証することが推奨されています。そのため、OIDC認証機能を利用しても依然としてJWTの検証は実装する必要がありました。 (JWT検証機能を使う場合でも、信頼するALBからのリクエストであることを何らかの仕組みで担保する必要があることに注意してください)
セキュリティを確保するには、要求に基づいて認証を行う前に署名を検証し、JWT ヘッダーの signer フィールドに、想定される Application Load Balancer ARN が記載されていることを確認します。
JWT検証機能のメリット
セキュリティ
今回のアップデートにより、JWT検証のロジックを自前で実装する必要がなくなります。
通常、JWTの検証はライブラリで実施した上で、各種クレーム検証をアプリケーションコードで自前実装することが多いと思います。 この時、クレーム検証のロジックが間違っていたりすると脆弱性に直結します。
よくある致命的なミスはexpクレームの検証ができていないことでしょう。
「exp」クレームの処理では、現在の日付/時刻が「exp」クレームにリストされている有効期限の日付/時刻より前でなければならない(MUST)。
RFC 7519 - JSON Web Token (JWT) 日本語訳
ALBのJWT検証機能を使うことで「iss」(発行者)と「exp」(有効期限)の検証が強制されるため、安全を担保しやすくなります。
コスト効率
JWT検証にはCPUによる計算が必要なので、サーバーのリソースを使用します。 当然、一度の検証の処理は重くありませんが、サーバーに到達する全てのリクエストごとに発生するコストです。JWT検証の負荷をALBに寄せることで、リクエスト数が多いサーバーにおいてはサーバー負荷を減らすことにも繋がります。
処理負荷のをALBに押し付けることになるためALBの費用が増加するのではと思いましたが、現状JWT検証の利用による追加の費用はないようです。
費用についての正式な情報は公式サイトをご確認ください。 Elastic Load Balancing pricing
おわりに
ALBのJWT検証機能は、私にとっては嬉しいアップデートでした。 今後もこういったアップデートを見逃さず、アプリケーション設計に取り入れて行きたいです。