「Cross-Site Request Forgery(CSRF)」攻撃は、一般のWebサービスでも珍しくありません。悪意のある外部サービスへユーザーをアクセスさせたり、特定のURLへの誘導などをきっかけに、ユーザーの意図しない機能を実行させたりする攻撃です。
例えばブログサービスやSNSがCSRF対策を怠ると、悪意のある第三者により、標的となったログイン中のユーザーが、犯罪予告のような意図せぬ記事投稿をさせられる恐れがあります。
OAuth 2.0ではCSRF攻撃の目的が多少異なります。標的となったユーザーに対し、攻撃者が自らのProtected Resourceにアクセスする許可を与えることを意味します。
これでは攻撃にならないように思えます。そこで、攻撃者のユーザーデータにアクセスすると、何が問題になるのか、例を2つ紹介しましょう。
ClientとAuthorization Server、Resource Serverの間でプライベートなデータをやりとりする場合を考えます。
CSRF攻撃は、標的ユーザーのClientアカウントに対して、攻撃者のアカウントにひも付くオンラインストレージへのアクセスを許可させます。これだけで攻撃者は標的ユーザーのプライベートな画像や動画にアクセス可能になります。
ClientがソーシャルログインにOAuth 2.0を利用しているとします。
CSRF攻撃によって、標的ユーザーのClientアカウントと攻撃者のAuthorization Serverのアカウントを用いたソーシャルログイン機能が有効になります。この場合、攻撃者は標的ユーザーのClientアカウントに簡単にログインできるようになります。
CSRF攻撃の流れを図2にまとめました。どこに脆弱性があるのか分析してみましょう。
つまり、攻撃者の環境で生成されたAuthorization ResponseをClientが標的ユーザーの環境で受け付けてしまう実装になっている点が問題になります。
CSRF攻撃を防ぐには、図3の流れになるように対策を採ります。
ClientからAuthorization ServerにResource Ownerを送る際のAuthorization Requestへ、「stateパラメーター」と呼ぶClientのセッションにひも付く値を含めるように改善します(図3中の青い部分)。Authorization ServerはClientに戻るAuthorization Responseにも、同じstateパラメーターの値を含めます。このためstateパラメーターの値をClientが検証して、同一セッション上の処理だと確認できます。同一セッションでなければリジェクトします(赤い矢印)。
攻撃者は自らのセッションにひも付くstateパラメーターを知ってはいても、標的となるユーザーのセッションにひも付くstateパラメーターを知ることは難しいため、CSRF攻撃の手順4を防止できます。
攻撃というとどうしても「攻撃者に×××を奪われる可能性がある」といったイメージがあります。しかし、攻撃者のリソースとひも付けられるリスクがあることを覚えておくとよいでしょう。
Webブラウザ上で動作するJavaScriptのアプリケーションなどを対象とした「Implicit Grant Flow」と呼ばれる処理フローが、OAuth 2.0にあります。
このフローには、Authorization ServerからResource Ownerを経由してClientに戻る際のAuthorization Responseに「Access Token」の値が含まれています(図4中の青い矢印)*2)。ClientはそのAccess Tokenを用いてAPIアクセスを行います。ここまではOAuth 2.0で想定されているユースケースです(図1中の薄い灰色の長方形で囲んだ部分に相当)。
ここで、Clientがソーシャルログインの機能を実装しようとして自らのバックエンドサーバと通信しているようなケースを考えます。
ClientはバックエンドサーバにAccess Tokenを送り(赤い矢印)、バックエンドサーバはClientと同様にAPIアクセスを行い、取得したユーザー識別子を用いてログイン状態にする、という実装が考えられます。
*2) Access TokenはRFC 6749と同時期に公開されたRFC 6750で定義されている。
「Token Replace Attack」は、この「バックエンドサーバに送るAccess Tokenを別のものに置き換える」ことでClientに別のユーザーでログインできるようにします。
図5に示した攻撃の流れは次の通りです。
一般のOAuth 2.0実装で使われているAccess Tokenは、RFC 6750で定義された”Bearer Token”と呼ばれており、単体でAPIアクセスが可能です。つまり、APIアクセスを成功させるために攻撃者が利用するAccess Tokenには制約がなく、Authorization ServerがこのClientに対して発行したものでなくても構いません。同じAuthorization Server、Resource Serverに対するClientであり、第三者のAccess Tokenを保持していれば、この攻撃が可能となります。
ここまでを踏まえると、攻撃が成功する前提条件は次のようになります。
この前提条件をつぶすことが対策になります。2種類の対策があります。
(1)については、「Authorization Code Flow」の利用が適しています。バックエンドサーバとの間でAccess Tokenのやりとりが必要ないからです。Authorization Serverによっては、Access TokenがどのClientに向けて発行されたものかを確認できるようなAPIを提供しています。
(2)では、別のClientに発行されたAccess Tokenの利用を防止できます。ただし、詳細な実装内容はAuthorization Serverにより異なるので注意が必要です。
Token Replace Attackは、Access Tokenを入手できれば実行できるため、難易度の高い攻撃ではありません。これを意識して、Clientで安全な実装をする必要があります。
例えば、SNSのプロフィール情報を用いた占いサービスが悪意を持って構築された場合を考えてみましょう。OAuth 2.0の仕組みを用いてプロフィール情報へのアクセス許可を求めて来た場合、仕様用途も(一見)シンプルなため、ユーザーは比較的簡単に許可してしまうかもしれません。しかし、この占いサービスの開発者が悪意を持っていたら、取得したAccess Tokenを脆弱性のある別のサービスへの攻撃に利用できるのです。
Copyright © ITmedia, Inc. All Rights Reserved.