PR

APIセキュリティのハードニング

2020年7月22日(水)
田畑 義之
連載3回目となる今回は、前回紹介したシステムに対する攻撃のタイプを紹介し、APIセキュリティのハードニングに則った対応策による堅牢化の手法を紹介します。

第三回は、第二回で構築したシステム(図1)をOAuth 2.0のセキュリティベストプラクティスに則って、より堅牢にしていきます。

図1:システム構成

図1:システム構成

攻撃の側面の把握

セキュリティを考えるにあたって重要なのは、攻撃の側面について知ることです。まずは、攻撃者がどこを攻撃してくるのかを把握します(図2、表1)。

図2:攻撃の側面

図2:攻撃の側面

表1:攻撃の側面と攻撃の例

#攻撃の側面攻撃の例
通信経路通信を盗聴し、ユーザの秘密情報(ユーザ名/パスワード)やトークンの情報を不正取得する
外部アプリ攻撃者の作成した外部アプリにユーザを誘導し、秘密情報を不正取得する
APIゲートウェイ攻撃者の作成したAPIゲートウェイにユーザ/クライアントを誘導し、APIコールに付与されたアクセストークンを不正取得する
ブラウザスクリプトなどを実行し、認可リクエスト/認可レスポンスを操作して、アクセストークンを不正取得する
認可サーバ攻撃者の作成した認可サーバにユーザ/クライアントを誘導し、秘密情報を不正取得する

ベストプラクティスによると、上記攻撃の側面は、1箇所のみならず、複数箇所(例えば外部アプリとAPIゲートウェイなど)が攻撃者のコントロール下にあることも想定する必要があります。以降では、攻撃の側面ごとに、代表的な攻撃方法とその対応方法を説明します。なお、ここではFintechアプリを例に用います。つまり、APIゲートウェイおよびAPIサーバを銀行が提供し、外部アプリは銀行の口座を管理する(残高照会や送金ができる)Fintechアプリであると仮定します(図3)。

図3:Fintechアプリの例

図3:Fintechアプリの例

攻撃の側面①:通信経路

まずは、通信経路が攻撃者のコントロール下にある場合を考えます。通信経路が攻撃者のコントロール下にある場合、通信が暗号化されていない限り、すべての通信は盗聴される危険性があります。例えばResource Owner Password Credentials Grantの場合、以下のようなコマンドでトークンエンドポイントをコールするので、通信からはユーザの秘密情報(ユーザ名/パスワード)を取得できます。

リスト1:

$ curl http://<認可サーバhostname>:8080/auth/realms/sample_service/protocol/openid-connect/token -d "grant_type=password&client_id=sample_application&client_secret=<client secret>&username=sample_user&password=<password>&scope=openid"

攻撃者は取得したユーザの秘密情報を自身の使用する外部アプリに入力することで正規ユーザになりすまし、正規ユーザの口座から攻撃者自身の口座への送金要求ができます(図4)。

図4:通信経路からのユーザ秘密情報取得

図4:通信経路からのユーザ秘密情報取得

この攻撃の対応方法として、通信をTLSで暗号化する方法があります(図5)。通信をTLSで暗号化することで、盗聴が格段に難しくなります。

図5:TLSで暗号化

図5:TLSで暗号化

攻撃の側面②:外部アプリ

次に、外部アプリが攻撃者のコントロール下にある場合を考えます。外部アプリが攻撃者のコントロール下にある場合、当該アプリに入力したユーザの秘密情報が盗まれる危険性があります。また、ユーザが許可していない操作を、ユーザのリソースに対して実行される危険性があります。まずは、ユーザの秘密情報を不正取得する例です。攻撃者は取得したユーザの秘密情報を自身の使用する外部アプリに入力することで正規ユーザになりすまし、正規ユーザの口座から攻撃者自身の口座への送金要求ができます(図6)。

図6:外部アプリからのユーザ秘密情報取得

図6:外部アプリからのユーザ秘密情報取得

この攻撃の対応方法として、OAuth 2.0の認可フローをResource Owner Password Credentials GrantからAuthorization Code Grantに変更する方法があります(図7)。Authorization Code Grantに変更することで、ユーザの秘密情報が外部アプリを経由することがなくなるので、外部アプリからユーザの秘密情報を取得できなくなります。

図7:Authorization Code Grant

図7:Authorization Code Grant

次に、ユーザが許可していない操作を外部アプリが実行する例です。攻撃者は、正規ユーザから送金要求の同意を得ていないにも関わらず、認可サーバから払い出されたアクセストークンを付与することで、正規ユーザから攻撃者自身の口座への送金要求ができます(図8)。

図8:外部アプリによるアクセストークン悪用

図8:外部アプリによるアクセストークン悪用

この攻撃の対応方法として、アクセストークンのscopeクレームを用いる方法があります(図9)。scopeクレームを用いることで、外部アプリは許可された範囲外のリソースを操作できなくなります。

図9:scope

図9:scope

攻撃の側面③:APIゲートウェイ

次に、APIゲートウェイが攻撃者のコントロール下にある場合を考えます。APIゲートウェイが攻撃者のコントロール下にある場合、当該APIゲートウェイに対するAPIコールに付与されたアクセストークンが盗まれる危険性があります。攻撃者は取得したアクセストークンを用いて正規のAPIゲートウェイを通じ、正規ユーザの口座から攻撃者自身の口座への送金要求ができます(図10)。

図10:APIゲートウェイからのアクセストークン取得

図10:APIゲートウェイからのアクセストークン取得

この攻撃の対応方法として、アクセストークンのaud(Audience)クレームを用いる方法があります(図11)。audクレームを用いることで、ユーザが許可していないAPIゲートウェイはリソースを操作しなくなります。

図11:aud

図11:aud

audクレームを用いたアクセス制御を導入することで、リソースを操作できるAPIゲートウェイを特定のAPIゲートウェイのみに限定することはできますが、裏を返せばaudクレームで指定されてさえいれば、指定されたAPIゲートウェイは攻撃者の指示によってリソースを操作してしまいます。

そこで登場するのが、リソース操作の要求元、つまり外部アプリを限定する方法です。その一例として、OAuth MTLS(OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens: RFC8705)を用いる方法があります(図12)。OAuth MTLSを用いることで、トークンを受け取った外部アプリ以外からのAPIコールに対して、APIゲートウェイはリソースを操作しなくなります。

図12:OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens

図12:OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens

攻撃の側面④:ブラウザ

次に、ブラウザが攻撃者のコントロール下にある場合を考えます。ブラウザが攻撃者のコントロール下にある場合、スクリプトなどを実行することで、認可リクエストや認可レスポンスを盗聴/改ざんされる危険性があります。

まずは、認可リクエストを改ざんする例です。例えばAuthorization Code Grantの場合、以下のようなURLで認可エンドポイントにアクセスします。

リスト2:

https://<認可サーバhostname>/auth/realms/sample_service/protocol/openid-connect/auth?response_type=code&client_id=sample_application&redirect_uri=https://<外部アプリhostname>/callback&scope=openid remittance sample_api_gateway

上記URLのclient_idとredirect_uriを以下のように書き換えることで、攻撃者は自身の使用する外部アプリに認可コードを飛ばすことができ、最終的に正規ユーザの口座から攻撃者自身の口座への送金要求ができます(図13)。

リスト3:

https://<認可サーバhostname>/auth/realms/sample_service/protocol/openid-connect/auth?response_type=code&client_id=evil_application&redirect_uri=https://<偽外部アプリhostname>/callback&scope=openid remittance sample_api_gateway
図13:ブラウザによる認可リクエスト改ざん

図13:ブラウザによる認可リクエスト改ざん

次に、認可レスポンスを盗聴する例です。例えばAuthorization Code Grantの場合、以下のような認可レスポンスがブラウザに返ってきます。

リスト4:

302 Found
Location: https://<外部アプリhostname>/callback?code=<authorization_code>

上記Locationヘッダから、認可コード(authorization_code)を取得し、自身の使用する外部アプリに送ることで、最終的に正規ユーザの口座から攻撃者自身の口座への送金要求ができます(図14)。

図14:ブラウザからの認可コード取得

図14:ブラウザからの認可コード取得

このような攻撃への対応方法としては、stateパラメータを用いる方法、nonceパラメータを用いる方法、そしてPKCE(Proof Key for Code Exchange:RFC7636)を用いる方法があります。

まずは、stateパラメータを用いる方法です(図15)。stateパラメータを用いることで、外部アプリは認可リクエストと認可レスポンスを同一セッションとしてバインドすることができ、外部アプリは対応する認可リクエストのない認可レスポンスを処理しなくなります。

図15:state

図15:state

次に、nonceパラメータを用いる方法です(図16)。nonceパラメータを用いることで、外部アプリは認可リクエストとトークンレスポンスを同一セッションとしてバインドすることができ、外部アプリは対応する認可リクエストのないトークンレスポンスを用いてAPIをコールしなくなります。

図16:nonce

図16:nonce

最後に、PKCEを用いる方法です(図17)。PKCEを用いることで、認可サーバは認可リクエストとトークンリクエストを同一セッションとしてバインドすることができ、認可サーバは対応する認可リクエストのないトークンリクエストに対し、トークンを返さなくなります。

図17:PKCE

図17:PKCE

上述したstateパラメータを用いる方法、nonceパラメータを用いる方法、PKCEを用いる方法は、すべて認可コードを不正取得されたときの対応方法です。それに対し、そもそも認可コードの不正取得自体を困難にする方法として、OAuth 2.0 Form Post Response Modeを用いる方法があります(図18)。Form Post Response Modeを用いることで、クエリ部分ではなく、リクエストボディ部分に認可コードが記載されるため、認可コードが盗聴されにくくなります。

図18:OAuth 2.0 Form Post Response Mode

図18:OAuth 2.0 Form Post Response Mode

攻撃の側面⑤:認可サーバ

最後に、認可サーバが攻撃者のコントロール下にある場合を考えます。認可サーバが攻撃者のコントロール下にある場合、当該サーバに送ったユーザの秘密情報、認可コード、クライアントの秘密情報が盗まれる危険性があります。ここではブラウザも攻撃者のコントロール下にあることを想定します。

まずは、ユーザの秘密情報を盗聴する例です。例えばAuthorization Code Grantの場合、以下のようなURLで認可エンドポイントにアクセスします。

リスト5:

https://<認可サーバhostname>/auth/realms/sample_service/protocol/openid-connect/auth?response_type=code&client_id=sample_application&redirect_uri=https://<外部アプリhostname>/callback&scope=openid remittance sample_api_gateway

上記URLの認可サーバhostnameを以下のように書き換えることで、攻撃者は自身の使用する認可サーバに認可リクエストを飛ばすことができ、最終的に正規ユーザの口座から攻撃者自身の口座への送金要求ができます(図19)。

リスト6:

https://<偽認可サーバhostname>/auth/realms/sample_service/protocol/openid-connect/auth?response_type=code&client_id=sample_application&redirect_uri=https://<外部アプリhostname>/callback&scope=openid remittance sample_api_gateway
図19:認可サーバからのユーザ秘密情報取得

図19:認可サーバからのユーザ秘密情報取得

この攻撃の対応方法として、一般的なフィッシング対策があります(図20)。フィッシング対策は認証部分の技術であり、今回ターゲットとしているOAuth 2.0やOIDCの範囲からは外れるため詳細は割愛しますが、例えば、ユーザが正規認可サーバであることに気付きやすくする仕組み(ユーザが登録した画像を表示するなど)をログイン画面に施したり、2要素認証を導入したりする方法などがあります。

図20:フィッシング対策

図20:フィッシング対策

次に、トークンリクエストを盗聴する例です。例えばAuthorization Code Grantの場合、以下のような認可レスポンスがブラウザに返ってきます。

リスト7:

302 Found
Location: https://<外部アプリhostname>/callback?code=<authorization_code>

上記Locationヘッダのコールバックエンドポイントを以下のように書き換えることで、認可コードが攻撃者の使用する認可サーバから届いたと外部アプリに錯覚させ、攻撃者は自身の使用する認可サーバにトークンリクエストを飛ばすことができ、最終的に正規ユーザの口座から攻撃者自身の口座への送金要求ができます(図21)。

リスト8:

302 Found
Location: https://<外部アプリhostname>/callback_for_evil_auth_server?code=<authorization_code>
図21:認可サーバからの認可コード取得

図21:認可サーバからの認可コード取得

この攻撃への対応方法としては、コールバックエンドポイントと認可サーバとの突き合わせをする方法、OAuth MTLSを用いる方法があります。

まずは、コールバックエンドポイントと認可サーバとの突き合せをする方法です(図22)。外部アプリが使用する認可サーバが1つであれば問題ありませんが、やむなく2つ以上の認可サーバを使用する場合、redirect_uri(つまりコールバックエンドポイント)は認可サーバごとに変えて、どの認可サーバから来た認可レスポンスかを区別できるようにします。その上で、認可リクエストの送り先、認可レスポンスの送り元、加えてトークンリクエストの送り先の認可サーバがすべて一致するかを確認することで、攻撃者のコントロール下にある認可サーバにトークンリクエストを送らないようにします。

図22:コールバックエンドポイントと認可サーバとの突き合わせ

図22:コールバックエンドポイントと認可サーバとの突き合わせ

次に、OAuth MTLSを用いる方法です(図23)。こちらはAPIゲートウェイが攻撃者のコントロール下にある場合の攻撃の対策方法として説明したものと同じです。OAuth MTLSを用いることで、たとえ攻撃者がトークンリクエストを盗聴できたとしても、トークンリクエストのTLSネゴシエーションの時に、攻撃者は認可サーバに対し正規外部アプリのクライアント証明書を提示できないため、認可サーバはトークンを返さなくなります。

図23:OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens

図23:OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens

次回は、今回紹介したハードニング方法を、実際にKeycloakを用いて設定し、動作を確認していきましょう。

株式会社 日立製作所
OSSソリューションセンタにて、API管理や認証周りのOSSの開発/サポート/普及活動に従事。3scaleおよびkeycloakコミュニティのコントリビュータであり、多数のコードをコミットしている。

連載バックナンバー

セキュリティ技術解説
第3回

APIセキュリティのハードニング

2020/7/22
連載3回目となる今回は、前回紹介したシステムに対する攻撃のタイプを紹介し、APIセキュリティのハードニングに則った対応策による堅牢化の手法を紹介します。
システム開発技術解説
第2回

Keycloakのインストールと構築例

2020/6/25
連載2回目となる今回は、前回紹介したシステムの構築方法をご紹介します。
システム開発技術解説
第1回

KeycloakによるAPIセキュリティの基本

2020/5/28
連載の1回目である今回は、Keyclooakの基本および、API保護が必要とされる背景について解説します。

Think IT会員サービス無料登録受付中

Think ITでは、より付加価値の高いコンテンツを会員サービスとして提供しています。会員登録を済ませてThink ITのWebサイトにログインすることでさまざまな限定特典を入手できるようになります。

Think IT会員サービスの概要とメリットをチェック

他にもこの記事が読まれています