【連載】世界一わかりみの深いOAuth入門 〜 その4:stateパラメーターによるCSRF対策 〜

こんにちは、サイオステクノロジー武井です。今回は、ちょっと難解なOAuthをわかりみ深く説明してみたいと思います。本記事は、私がOAuthを理解するまでの備忘録みたいなものになり、説明が至らないこと多々あると思いますが、生暖かい目で見守って頂けますと幸いです。

全4回シリーズでお届けする予定で、今回は最後の第4回目となります。

  1. その1:OAuthってなに?
  2. その2:アクセストークンとリフレッシュトークン
  3. その3:OAuthを認証に使うことの危険性
  4. 今回はこちら → その4:stateパラメーターによるCSRF対策

 

stateパラメーターとは?

stateパラメーターは、CSRF(クロスサイトリクエストフォージェリ)対策で付与します。CSRFとはユーザー本人がいとしないリクエストを、悪意のある第三者によって強制する攻撃のことです。だいぶ昔には、mixiの「はまちちゃん」で有名になりましたが、OAuthやOpenID Connectにも同様のリスクがあります。その対策がstateパラメーターになります。ただ、stateパラメーターで対策するのは、「なりすまされ」というのであって、ここが今までのCSRF対策とイマイチ違いがわかりにくい点になります。(少なくとも私は理解に苦しみました^^;)

stateパラメーターの説明

stateパラメーターのない世界と、ある世界ではどのように違うのかを説明することで、stateパラメーターの有効性を説明します。とあるシステムを例に上げることとします。そのシステムの登場人物は以下のとおりとなります。

Screen Shot 2018-04-08 at 21.36.55 ストレージサービス・・・クラウド上のオンラインストレージサービスです。ユーザーは自分の領域に任意のファイルを格納することが出来ます。
Screen Shot 2018-04-08 at 21.41.48 サービスA・・・ストレージサービスを利用するサービスです。OAuth認証を用いて、ユーザーにストレージサービスを利用させます。
Screen Shot 2018-04-08 at 21.50.09 Aさん・・・サービスAの正規な利用者です。
Screen Shot 2018-04-08 at 21.51.43 悪い人・・・ユーザーAさんに対してCSRF攻撃を行おうとする攻撃者です。

stateパラメーターのない世界

stateパラメーターのない世界では、どのような悪いことが起こるのかを説明します。

 

まず、以下のようなシステムを想定します。ストレージサービスは外部にAPIを公開しており、そのAPIでファイルをアップロードできます。そしてAPIの認証はOAuthで行います。サービスAはOAuth認証を用いて、ユーザーがサービスAにアップロードした画像をストレージサービスにもアップロードします。悪い人は、まず、サービスAにアクセスして、OAuth連携を開始します。

Screen Shot 2018-04-08 at 22.02.10

 

悪い人は、ストレージサービスの認可画面にリダイレクトされます。「はい」をクリックします。

Screen Shot 2018-04-08 at 22.04.45

 

すると、認可コードをクエリパラメーターに付与した、サービスAへのリダイレクトが発生します。しかし、悪い人は、ここで、リダイレクト先のURLだけ取得をし、サービスAにリダイレクトさせないようにします。この実現方法は色々ありますが、独自のHTTPクライアントのプログラムを開発して、Locationヘッダからリダイレクト先のURLだけを抜き取り、実際のリダイレクトはさせないようにすればよいと思います。

Screen Shot 2018-04-08 at 22.06.01

 

悪い人は、先程取得したURLをメールなどの手段でAさんに送付して、AさんにそのURLにアクセスさせます。すると、アクセストークンを取得する主体は、悪い人からAさんに移り、悪い人のアクセストークンを取得するプロセスは、今後、Aさんのセッションで行われることとなります。ここがキモです。

Screen Shot 2018-04-08 at 22.09.17

 

サービスAは、認可コードをストレージサービスに渡して、アクセストークンを要求します。

Screen Shot 2018-04-08 at 22.13.38

 

ストレージサービスは、悪い人のストレージにアクセスするためのアクセストークンをサービスAに返します。なぜそうなるかというと、アクセストークンを取得するために発行された認可コードは、悪い人によって発行されたものだからです。

そして、そのアクセストークンは、ユーザーAのデータベースに格納されます。なぜそうなるかというと、認可コードをサービスAに渡したのは、他ならぬAさんだからです。

Screen Shot 2018-04-08 at 22.12.18

 

つまり、Aさんは、悪い人のアクセストークンを取得し、悪い人のストレージに自由にアクセスできるようになりました。他人のストレージを自由にアクセスできるわけですから、あまり害はないように思えますが、ここで一番まずのは、Aさんが知らない間にこのような状況に陥ってしまったことです。これは、「乗っ取り」ではなくて「乗っ取られ」といわれるもので、例えば、他の人に漏らしたくないような情報を自分のフォルダにアップロードしたつもりが、実は悪い人のフォルダに知らない間にアップロードしていることになり、悪い人はAさんのプライベートを見ることが出来てしまうわけです。

Screen Shot 2018-04-10 at 8.55.36

stateパラメーターのある世界

stateパラメーターがあると、先程のような被害を防ぐことが出来ます。先程のケースで、stateパラメーターを付与した場合にどの様になるかを説明してみます。

 

悪い人は、まず、サービスAにアクセスして、OAuth連携を開始します。ここまでは、先程と一緒です。

Screen Shot 2018-04-08 at 23.36.12

 

悪い人は、ストレージサービスの認可画面にリダイレクトされます。先ほどと違うのは、サービスAがリダイレクト先のURLのパラメーターにstate=xyzという値を付与していることです。さらに、このとき、サービスAは、このstateの値を悪い人のセッションに紐づけます(Javaでいえば、request.getSession().setAttribute(“state”,”xyz”)とします)。

Screen Shot 2018-04-08 at 23.42.28

 

すると、認可コードをクエリパラメーターに付与した、サービスAへのリダイレクトが発生します。しかし、悪い人は、ここで、リダイレクト先のURLだけ取得をし、サービスAにリダイレクトさせないようにします。先ほどと違うのは、ストレージサービスは、1つ前のプロセスで渡されたstateパラメーターをそのまま同じように、リダイレクト先のURLに付与しているところです。

Screen Shot 2018-04-08 at 23.47.50

 

先程と同様に、悪い人は、先程取得したURLをメールなどの手段でAさんに送付して、AさんにそのURLにアクセスさせます。

Screen Shot 2018-04-08 at 23.50.31

 

「stateパラメーターのない世界」と決定的に違うのがこのプロセスです。サービスAは、URLに付与されているstateパラメーターと、アクセスしてきたユーザーのセッションに格納されているstateパラメーターを比較して、一致していなければ不正なアクセスとして、処理を中断します。認可コードを取得したのは悪い人なので、stateパラメーターは悪い人のセッションの中に格納されていますが、認可コードをもとにアクセストークンを要求したのはAさんです。もちろん、Aさんのセッションの中には、stateパラメーターの値が入っていないので、下記のように不一致となります。このような理路により、CSRF攻撃を防御することが可能です。

Screen Shot 2018-04-08 at 23.55.47

まとめ

いかがでしょうか?4回の連載でOAuthについて説明しました。至らぬ点多々あったかもしれませんが、もし今回の説明がOAuthに対する理解の一助になれば幸いです。

 

 

ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

10人がこの投稿は役に立ったと言っています。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です