FAPIとKeycloakの概要
はじめに
サービスデリバリのアジリティを高めるために、今やサービス開発にAPIを利用することは必要不可欠となっています。また既存サービスに新たな価値を付与するために、APIを公開することも常套手段の一つとなっています。このようにAPIに触れる機会が日常にあふれている一方、APIに対して適切なセキュリティ設計を行わなかったために、機密性の高い情報が漏えいしてしまったり、金融取引に関わる不正操作を許してしまったりという事故や事件は後を絶ちません。攻撃者による攻撃が日々進化をし続けている中、APIを公開するシステムに求められるセキュリティ要件は日々高度化しています。
そんな中で注目を集めているのが、Financial-grade API Security Profile(以下、FAPI)です。FAPIは元々、金融分野において浸透していた、スクリーンスクレイピング※1による自動ログインを規制し、安全な代替手段を提供することを目的に策定された仕様ですが、現在はOAuth 2.0やOpenID Connect 1.0で規定されているレベルよりも高いレベルのセキュリティを必要とする、あらゆる分野のAPIに適用可能な仕様となっています。2021年3月21日にFAPI 1.0がファイナル版としてFixしたこともあり、世界各地でそれに準拠する動きが活発になっています。
※1 一般的には、画面情報を取得してその中身を抽出する技術を指すが、ここではFinTechアプリなどがユーザからパスワードを取得し、ユーザの代わりに(ユーザになりすまして)金融機関のアプリからユーザの情報を取得することを指す。
以下にいくつかの例を紹介します。
Open Banking(イギリス)
金融サービス向けAPIの標準仕様と、金融サービス向けAPIを利用したサービスを運用するシステムです。英国の政府関連機関であるCompetition and Markets Authority(CMA)が、銀行業界に金融サービスのオープン化を命じたのがきっかけで成立しました。もともと独自のAPI Security Profileを策定していましたが、現在のAPI Security ProfileはFAPI 1.0をベースとして策定されています。※2
※2 The OBIE announces new Open Data and Read/Write Releases
Consumer Data Right(オーストラリア)
消費者が自身のデータをコントロールし、さまざまなサービスを比較可能な形で容易に利用できるようにすることを狙いとしたシステムです。政府関連機関であるAustralian Competition&Consumer Commission(ACCC)が主導しています。FAPIをベースとした独自のAPI Security Profileを策定しています。
Open Banking Brasil(ブラジル)
金融サービス向けAPIの標準仕様と、金融サービス向けAPIを利用したサービスを運用するシステムです。Banco Central do Brasil(BCB)とNational Monetary Council(CMN)が主導しています。FAPIをベースとした、独自のAPI Security Profileを策定しています。
オープンAPI(日本)
銀行がFintech企業などにAPIを提供し、顧客の同意に基づいて、銀行システムへのアクセスを許諾することを指す用語です。金融庁の金融制度ワーキング・グループの報告で定義され、2017年6月の銀行法改正によってその導入の動きが活発になりました。全銀協の報告書では、銀行はFAPIへの準拠を検討する必要があり、準拠をしない場合はその合理性と許容性を検討することが望ましいとされています。
連載の第1回となる今回は、このFAPI 1.0の概要と、OSSのIAM(Identity and Access Management)製品であるKeycloakのFAPIサポートまでの歩みをご紹介します。
FAPI 1.0の概要
FAPI 1.0には、パート1のBaselineとパート2のAdvancedがあります。両者のユースケースの違いは規定されていませんが、BaselineはAdvancedに包含されており、またより高いレベルのセキュリティを必要とする、機密性の高い情報のやり取りや金融取引用のAPIは、Advancedへの準拠が望ましいとされています。そのため本連載では、パート2のAdvancedを中心に見ていきます。
冒頭でご紹介した通り、FAPIは元々、金融分野において浸透していた、スクリーンスクレイピングによる自動ログインを規制し、安全な代替手段を提供することを目的に策定された仕様です。スクリーンスクレイピングによる自動ログインの例を図1に示します。
上記の方法には一見して特に問題がないようにも見えるかもしれませんが、この方法には以下のような危険性が潜んでいます。
- 家計簿アプリに脆弱性がある場合、A銀行のWebサービスにアクセスするためのユーザIDとパスワードが漏えいしてしまう可能性がある
- 家計簿アプリが悪意のある攻撃者によって作成されたアプリである場合、「残高照会」処理だけではなく、「送金」処理もできてしまう
そのため図2のように、認可サーバとアクセストークンを用いた安全な代替手段を用いる必要があります。
認可サーバとアクセストークンを用いた安全な代替手段を用いることにより、以下のメリットが得られます。
- 家計簿アプリにはユーザIDとパスワードを渡さないため、たとえ家計簿アプリに脆弱性があっても、ユーザIDとパスワードが漏えいしない
- ユーザの認可に応じたアクセストークンが発行されるため、たとえ家計簿アプリが悪意のある攻撃者によって作成されていたとしても、ユーザが認可していない「送金」処理はできない
さて、ここまで述べた内容は、あくまでFAPI 1.0の前提となる基本的な考え方です。また、ここまでに述べた内容だけであれば、FAPI 1.0は必要なく、FAPI 1.0がベースとするOAuth 2.0やOpenID Connect 1.0の認可コードフローに適切に準拠しているだけで十分に実現できます。
参考までに図3に、OAuth 2.0やOpenID Connect 1.0の認可コードフローを示します。クライアントを家計簿アプリ、リソースサーバをAPIサービスなどと読み替えることで、上述した認可サーバとアクセストークンを用いた安全な代替手段を実現できていることがわかるかと思います。
OAuth 2.0やOpenID Connect 1.0の認可コードフローは、その安全性と利便性から、今やAPIセキュリティのデファクトスタンダードとしてさまざまなAPIシステムで採用されています。しかし冒頭にも記載した通り、攻撃者による攻撃は日々進化をし続けており、OAuth 2.0やOpenID Connect 1.0の認可コードフローでは防げない攻撃が報告されるようになってきています。
FAPI 1.0では、そのような攻撃を防ぐためのより高いセキュリティ仕様を、認可サーバが準拠すべきこと、クライアントが準拠すべきこと、リソースサーバが準拠すべきことのそれぞれに分けて規定しています。ここでは、FAPI 1.0の仕様のすべてに言及するのは難しいため、特に注目すべき仕様である「認可リクエストや認可レスポンスの改ざん対策」に関する仕様と「アクセストークン横取り対策」に関する仕様の2つについてご紹介します。
認可リクエストや認可レスポンスの改ざん対策に関する仕様
認可コードフローに対する最も有効な攻撃方法として、認可リクエストや認可レスポンスを改ざんする攻撃があります。
認可リクエストや認可レスポンスは次のようにブラウザ経由のリダイレクトでやり取りするため、攻撃者が改ざんしやすいという特徴がありました。
HTTP/1.1 302 Found Location: https://server.example.com/authorize?response_type=code&scope=openid&client_id=s6BhdRkqt3&state=af0ifjsldkj&nonce=n-0S6_WzA2Mj&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb& code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM&code_challenge_method=S256
HTTP/1.1 302 Found Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&state=af0ifjsldkj
例えば認可リクエストのredirect_uriを改ざんして認可コードを盗聴したり、認可レスポンスのcodeに盗聴した認可コードを代入して被害者用のトークンを取得したりするような攻撃が考えられます。このような認可リクエストや認可レスポンスを改ざんする攻撃に対して、FAPI 1.0では認可サーバやクライアントがその攻撃を検知できる仕組みを規定しています。具体的には、リクエストオブジェクトを用いる方法とIDトークンを分離署名(Detached Signature)として用いる方法です。
1つ目のリクエストオブジェクトを用いる方法は、認可リクエストを改ざんする攻撃への対策です。この方法では、認可リクエストにリクエストオブジェクトを付与します。リクエストオブジェクトとは、認可リクエストのパラメータ群を署名付きJWT(JSON Web Token)であるJWS(JSON Web Signature)としてまとめたもので、OpenID Connect 1.0で規定されています。認可サーバは、このリクエストオブジェクトの署名を検証することで、認可リクエストが改ざんされているかどうかや、リクエストオブジェクトを作成したクライアントがどのクライアントであるかを確認することができます。
HTTP/1.1 302 Found Location: https://server.example.com/authorize?response_type=code%20id_token&scope=openid&client_id=s6BhdRkqt3&state=af0ifjsldkj&nonce=n-0S6_WzA2Mj&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb& code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM&code_challenge_method=S256&request=<リクエストオブジェクト>
2つ目のIDトークンを分離署名(Detached Signature)として用いる方法は、認可レスポンスを改ざんする攻撃への対策です。この方法では、認可レスポンスに分離署名としてIDトークンを付与します。IDトークンには、c_hash(codeのハッシュ値)とs_hash(stateのハッシュ値)が格納されており、クライアントはこのハッシュ値と、実際に受け取ったcodeとstateから計算したハッシュ値を比較することで、認可レスポンスが改ざんされているかどうかを確認することができます。
HTTP/1.1 302 Found Location: https://client.example.com/cb#code=SplxlOBeZQQYbYS6WxSbIA&state=af0ifjsldkj&id_token=<IDトークン>
アクセストークン横取り対策に関する仕様
横取りしたアクセストークンを用いてAPIをコールするという攻撃も、認可コードフローに対して有効な攻撃方法です。
OAuth 2.0やOpenID Connect 1.0では、RFC 6750で規定されているBearerトークンを用いるのが一般的です。Bearerトークンには、「『トークンを所有している』という条件を満たせばそのトークンを利用することができる」という特徴があるため、一度アクセストークンを横取りされてしまうと、トークンを実際に受け取っていないクライアントでも正規クライアントと同じようにAPIをコールできるという危険性がありました。
このようなアクセストークン横取り攻撃に対して、FAPI 1.0ではリソースサーバがその攻撃を検知できる仕組みを規定しています。具体的には、RFC 8705で規定されているクライアント証明書を用いた送信者制約のあるアクセストークンを用いる方法(以下、OAuth MTLS)です。
OAuth MTLSでは、トークン要求時に認可サーバがアクセストークンにクライアント証明書のハッシュ値を紐づけ、APIコール時にリソースサーバがアクセストークンに紐づいているクライアント証明書のハッシュ値と、実際に受け取ったクライアント証明書から計算したハッシュ値を比較することで、トークンを要求したクライアントとAPIをコールしたクライアントが同一であることを確認できます。
ここでご紹介した仕様以外にも、FAPI 1.0にはさまざまな仕様が規定されています。適切な形でFAPI 1.0に準拠するためには、認可サーバ、クライアント、リソースサーバのすべてが足並みをそろえて、それらの仕様を実装することが求められます。
KeycloakのFAPIサポート
OSSのIAM製品であるKeycloakは、2021年6月18日に、FAPI 1.0に対応したKeycloak 14をリリースしました。ここでは、KeycloakのFAPIサポートに向けたこれまでの歩みを簡単にご紹介します。
KeycloakにおけるFAPIサポートが始まったのは、2018年2月にFAPIサポートに向けたJIRAチケット(KEYCLOAK-6767)の作成がきっかけでした。
このJIRAチケットをもとに、PKCE(Proof Key for Code Exchange、RFC 7636)やIDトークンの暗号化、OAuth MTLS(RFC 8705)などがエンハンスされていきました。また、2020年に発足したKeycloak初のSIG(Special Interest Group)であるFAPI-SIGも、KeycloakにおけるFAPIサポートを強力に後押ししました。FAPI-SIGとは、その名の通り、FAPIとその関連仕様をKeycloakでサポートするためのグループです。
上記のような活動を通じ、Keycloakは2021年6月18日にFAPI 1.0をサポートしました。また以下の通り、FAPI関連仕様も続々とサポートしています。
- Keycloak 13(2021年5月6日リリース)
- Client Initiated Backchannel Authentication(CIBA)のpollモード
- Keycloak 14(2021年6月18日リリース)
- FAPI 1.0 Baseline Security Profile
- FAPI 1.0 Advanced Security Profile
- Keycloak 15(2021年7月30日リリース)
- Client Initiated Backchannel Authentication(CIBA)のpingモード
- FAPI JWT Secured Authorization Response Mode for OAuth 2.0(JARM)
- FAPI Client Initiated Backchannel Authentication Profile(FAPI-CIBA)
- OAuth 2.0 Pushed Authorization Requests(PAR)
- Brazil : Open Banking Brasil Financial-grade API Security Profile
またFAPI-SIGでは以下の仕様に準拠するため、現在も活動を絶賛推進中です。
- FAPI 2.0 Baseline Security Profile
- FAPI 2.0 Grant Management for OAuth 2.0
- OAuth 2.0 Rich Authorization Requests(RAR)
- OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer(DPoP)
- EU : PSD2/eIDAS QWAC Verification Extension
第1回では、FAPIとKeycloakの概要を紹介しました。次回は、KeycloakのFAPIサポートを説明する際には欠かせない、クライアントポリシーという機能をご紹介します。
連載バックナンバー
Think ITメルマガ会員登録受付中
全文検索エンジンによるおすすめ記事
- FAPI 1.0に準拠したクライアントアプリケーションと リソースサーバの作り方
- Keycloakを用いたハードニングの実装方法
- APIセキュリティのハードニング
- Oracle Cloud Hangout Cafe Season4 #4「マイクロサービスの認証・認可とJWT」(2021年7月7日開催)
- KeycloakによるAPIセキュリティの基本
- Keycloakの最前線を体感できるイベント「Keyconf 23」レポート
- Keycloakのクライアントポリシー(Client Policies)
- Keycloakのインストールと構築例
- クライアントポリシーを利用したKeycloakの設定方法と、FAPIリファレンス実装の紹介
- コンテナ上のマイクロサービスの認証強化 ~StrimziとKeycloak~