LoginSignup
7
1

More than 3 years have passed since last update.

OmniAuth の `/auth/:provider` で GET を受け付けるのはやめましょう (あるいは CVE-2015-9284 について)

Last updated at Posted at 2020-03-06

tl;dr

  • OmniAuth を使う場合、まずはユーザーを /auth/:provider のような URL に誘導すると思います。
  • このパスで GET リクエストを受け付けることは、セキュリティの観点から推奨されていません。
  • 具体的には、ユーザーが意図しないうちに、意図しない外部アカウントを紐付けてしまう危険性があります。
  • 代わりに POST を受け付けるようにしましょう。

どんな問題が発生するの?

前提

Web サイト A と B が存在するとします。
Web サイト A は OmniAuth を使って、「B のアカウントでログイン」のような機能を実装しています。そして /auth/site_b で GET リクエストを受け付けています。

アリスとマロリーがいるとします。アリスは被害者、マロリーは攻撃者です。
アリスは A のアカウントを持っていて、A にログイン済みですが、B のアカウントは紐付けていません。マロリーは B のアカウントを持っていて、あらかじめ A に対する認可を済ませてあります 1

攻撃開始

さて、マロリーの攻撃が始まります。
アリスはマロリーの攻撃により、マロリーのアカウントで B にログインした状態になってしまいました 2 。さらに続けて、マロリーは A の /auth/site_b に GET リクエストを投げされられてしまいました 3

アリスは B の認可画面にリダイレクトされますが、アリスは(マロリーのアカウント)で B にログインした状態なので、ID/PW を聞かれることはありません。さらに、マロリーは既に A に対する認可を済ませてあるので、認可画面も表示されません。ただちに A の /auth/site_b/callback にリダイレクトされます。

結果的に、 アリスの A アカウントにマロリーの B アカウントが、何の確認もなく紐付けられてしまいます 。言い換えると、マロリーがアリスの A アカウントに対して全権を手に入れてしまったのです。

この問題には CVE-2015-9284 という名前がついています。

何が原因なの?

ひとつは、アリスがマロリーの B アカウントでログインさせられてしまったことです。これは単に B の脆弱性で、今回のメインテーマではないので省略します。

もうひとつは、A の /auth/site_b が GET リクエストを受け付けていることです。
もしここが POST だけを受け付けて、なおかつ CSRF 対策が有効になっていれば、A にログインする前に必ず A の画面上で何らかのインタラクト(ログインボタンを押すなど)をユーザーに求めることができます。GET だと CSRF 対策ができないので、ユーザーに意識させないまま OAuth 連携処理を完了できてしまうのです。

どうすればいいの?

詳細は https://github.com/omniauth/omniauth/wiki/Resolving-CVE-2015-9284 に載っているので、それに従えばよさそうです。おおざっぱにいうと、 omniauth-rails_csrf_protection という gem を入れた上で、 /auth/:provider への GET リクエストを全て POST に置き換えていく、という流れになります。omniauth-rails_csrf_protection は、Rails に搭載されている CSRF 対策と同じメカニズムを OmniAuth の Rack ミドルウェア層に導入する Gem のようです。

重要なのは、この脆弱性が OmniAuth のアップデートによって直るたぐいのものではなく、我々 OmniAuth ユーザー側の対応が必要な点です。自分の Web サイトで /auth/:provider への GET リクエストが要件上必須かどうか検討して、必要なければ排除してしまいましょう。

余談

この問題のことを知ったのは、dependabot が作った PR がきっかけでした。

security ラベルが付いていたので、最初はこの v1.9.1 で脆弱性が直ったのかな?と思ったのですが、v1.9.1 のリリースノートにも「脆弱性を直した」とは書かれていません。どうやら、単に GitHub Advisory DatabaseAffected versions の更新が遅れているだけのようです。v1.9.1 でこの脆弱性が直っているわけではありません。

参考


  1. マロリーの B アカウントの「連携済みアプリ」欄にサイト A が表示されているような状態にする、という意味です。 

  2. 例えばサイト B に脆弱性があって CSRF された、など。 

  3. 例えば iframe でひっそりロードする、など。 

7
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
1