オーオース2・0におけるCSRF対策で認可サーバーができること

  • 4/2 追記
    • ブログのタイトルを「知ってるけどきっとそうじゃない。」に変更しましたが、それだとただの嘘だ、ということに気づきましたので、元のタイトルに戻します
    • 大変ご迷惑をおかけいたしました

  • 本日から、ブログのタイトルを「知ってるけどきっとそうじゃない。」に改めました
  • 今年度も、どうぞよろしくお願いいたします


By kidmissile - Identity Discs Acquired(2010) / CC BY-NC-ND 2.0

  • CSRFといえば、URLをクリックしただけで「こんにちはこんにちは!!」させられてしまう脆弱性であることを、ご存知の方は多いと思います
  • 最近は、フェイスブックアカウント等でログインできるウェブアプリケーション(応用ソフト)も増えてきましたが、そこで利用されている技術がオーオース2・0です
  • その部分にCSR脆弱性があると、いつの間にか、攻撃者のアカウントでログインさせられてしまう可能性があります
  • つまり、それに気づかないまま、攻撃者のアカウントに銀行口座情報等を登録してしまうかもしれないという、怖そうで怖くない少し怖い脆弱性なのです
  • さらに、既存のアカウントにオーオース2・0でログイン可能にする機能においてCSRFが成功すると、そのアカウントは乗っ取られてしまうでしょう
    • 「アカウントをフェイスブックアカウントと連携させる」的な機能のことです
  • そこで、クライアントがCSRFを理解しなくても脆弱性が生じないよう、認可サーバー側でできることを考えました
  1. 仕様をちょっぴり変える
    • 認可リクエストで、stateパラメーターを「推奨」から「必須」にする
    • 認可レスポンスに、stateパラメーターを含めない
    • アクセストークンリクエストで、stateパラメーターを必須とし、認可サーバーは認可リクエストで渡されたstateパラメーターとの一致を確認する
      • こうすれば、クライアントはおのずとstateパラメーターを、セッション情報として保存するでしょう
      • しかし、stateパラメーターは依然クライアントが決定するので、必須だからといって毎回、state=mendoiを送られてこないか心配です
  2. 仕様をもうちょっとだけ変える
    • クライアントは、stateパラメーターを発行するエンドポイントにリクエストする
    • 認可サーバーは、stateパラメーターを返す
    • 以下、認可サーバーから返されたstateパラメーターを用いて、1.と同様の手順をおこなう
    • 認可サーバーは、クライアントに発行したstateパラメーターであるか、常にチェックする
      • 認可サーバーから、適切なstateパラメーターを提供することができます
      • パラメーター名が、もはやstateとは言いがたいため、tokenなどに変更したほうがいいかもしれません
      • あとは、tokenをsecretとペアにしたり、すべてのリクエストとレスポンスに署名を付けたりすれば、さらにセキュアになるでしょう
  • いわゆるオレオレ仕様ですが、オーオース2・0は永久に更新され続ける仕様なので、多少違ってもばれることはないでしょう
  • もしかしたら、ドラフト100くらいで取り込まれるかもしれません