OAuth2.0とAuthorization Code Interception Attackについて
はじめに
もうすぐ去年のセキュキャンから1年ですね。
リレーブログです。
テーマはOAuthです。ここでは現在使われているOAuth 2.0とAuthorization Code Interception Attackという脆弱性について書こうと思います。
OAuth 2.0
OAuth 2.0は複数の異なるWEBサービスでアクセストークンを用いて、アクセス権限の認可を行うオープンスタンダード(RFC6749, RFC6750)です。
OAuthでは以下の4つのロール(役割)があります。
- Resource Owner
- エンドユーザー
- Client
- Resource Ownerに紐づくデータ(リソース)にアクセスするアプリケーション
- Resource Server
- ClientをリソースにアクセスさせるためのAPIを提供するサーバー
- Authorization Server
- Clientをリソースにアクセスさせるための認可サーバー
また、以下のような認可フローに沿って処理が進められていきます。
- Clientは認可サーバーの認可エンドポイントに認可リクエストを投げ、認可サーバーはResource Ownerに許可を求めます
- 成功すればClientは応答として短命の認可コードを受け取り、それを認可サーバーのトークンエンドポイントでアクセストークンと交換します
- 受け取ったアクセストークンを使ってClientはリソースサーバーのリソースにアクセスします
このフローを認可コードフローと呼びます。
このほかにもいくつか認可フローは定義されていますがここでは省略します。
Authorization Code Interception Attack
OAuth2.0の実装不備による脆弱性としてAuthorization Code Interception Attackというものがあります。 認可コードフローで成立する脆弱性で、認可エンドポイントからの応答に含まれる認可コードを横取りされ、悪意のあるClientがアクセストークンを取得できるというものです。
攻撃は次のように行われます。
- 攻撃者は標的となるClient(モバイルアプリケーション等)と同じカスタムURIスキームなどで起動するようなアプリケーションを作成し、標的ユーザーの端末にインストールする
- 標的Clientが認可サーバーからの認可のため、外部Webブラウザを起動する
- 認可に成功しカスタムURIスキームで、認可コードが渡される
- 攻撃者の作成したアプリケーションが起動してしまい、認可コードが奪われアクセストークンが攻撃者の手に渡る
カスタムURIスキームは複数のアプリケーションが同一の値を指定して登録できてしまうため、このような事が起こり得るのです。
対策
この脆弱性はRFC6749に沿って忠実に実装したとしても防ぐことはできません。
ですが拡張仕様としてRFC7636が作成されており、その通り実装することで対策が可能です。
RFC7636
RFC7636で策定されているのは、Proof Key for Code Exchange by OAuth Public Clients(OAuth PKCE)というものです。
OAuth PKCEでは、Clientは code verifier と呼ばれるランダムな値を作成し保存します。そしてそれをハッシュ化した code challenge という値を、認可リクエストの際に送信し、認可サーバーはそれを保存します。
認可コードからアクセストークンを取得する際は code verifier を一緒に送信し、認可サーバー側で保存してあるcode challenge と照合することで認可をリクエストしたClient以外がアクセストークンを受け取る事を防止できるのです。
おわりに
OAuthは調べてみると次々に脆弱性が出てきて驚きました。テーマと共に渡された資料でも認可制御の脆弱性は多いと書かれていたので気を付けたいですね。
ちなみに7月でリレーブログも終わるみたいなので、僕の記事としてはこれが最後になる、と思います。
全然関わってこなかった分野を勉強出来たり、インプットした知識をアウトプットするいい練習でもありました。
この活動のために開設したブログではありますが、不定期で更新は続けようと思います。
約1年、お疲れ様でした!