Cross Site Request Forgeriesの新しい形?

頭悪くない?って言われるかもですけど。。。

Cross Site Request Forgeriesの一般的な話

通常、Cross Site Request Forgeries(以降CSRFと記述)というと以下のような機能に対して攻撃を行うものであると思う。

CSRFのターゲットになる代表的な機能

  1. パスワード変更
  2. 登録情報変更
  3. 退会
  4. ショッピング
  5. 掲示板/日記への書き込み

特に、ここでは、混乱を避けるため、「攻撃者が直接行う」場合と、「ユーザに罠を踏ませる」場合とで、Webアプリケーションに対する被害/現象が同じものについては考えないものとする。

例えば、ショッピングで考えると、"罠を踏ませる時に攻撃者がユーザのあて先住所も指定しなければならない"というような場合は含まず、"罠を踏ませると自動的にユーザの登録情報からあて先住所を決定する"という場合を主に考える。

また、よくあるコメントスパム等の話も、対策がだいぶ違う*1のでCSRFの範疇には入れない。

さて、CSRFに対する対策だが、この脆弱性が認知されてからある程度議論されて大体以下のような感じに落ち着いてるのではないかなと思う(ウソがあったら教えてください)。

効果のある対策

  1. パスワードの入力をユーザに求める*2
  2. 認証状態管理に使ってるセッションIDをhiddenで埋め、次のページで認証状態の判定をCookieだけに依存しない処理にする
  3. セッションIDの代わりに攻撃者が推測できない値(ワンタイムトークンなど)をhiddenで埋めとく

よくある間違った対策

  1. POSTだから大丈夫
  2. リファラ(Referer: ヘッダ)をチェックすれば解決*3
  3. 確認画面を挟んでるから直接送信されることは無い
  4. セッション変数を使ってるから大丈夫

これも被害あるんじゃない?な話

で、Webアプリケーションにおいて、CSRFの対策がなされているのを見た事が無い機能がある。
それは、「ログイン」です。(今、頭悪っ!って思いました?)

CSRFでよく語られているのが、認証状態にある正規のユーザが、罠により自分の権限において意図しない処理を実行するというものだと思う。

しかし、ログイン機能に対するCSRFに於いては、「攻撃者の権限において、ユーザに自ら処理を行わせる」という構図になる。これは、被害的にはフィッシングみたいなもんと考えてもらうとよい。CSRFで直接何かが起こるというより、CSRF後の挙動が問題という感じ。

例えば、こんなメールが来たらどうだろう?*4

こちらは、○○(Webアプリの名前)の管理者です。

この足袋度、サーバのメンテナンスの際にデータの移行ミスによりお客様の情報が消えてしまいました。お手数ですが、下記URLよりアクセスを行い、再度情報を登録していただくようお願いいたします。

http://www.example.com/webapp/login?%6c%6f%67%69%6e%69%64=%74%65%73%74&%70%61%73%73%77%6f%72%64=%74%65%73%74%70%61%73%73

ここでは、視覚的に罠だということがわからないように、「loginid=test&password=testpass」という文字列をURLエンコードし「%6c%6f%67%69%6e%69%64=%74%65%73%74&%70%61%73%73%77%6f%72%64=%74%65%73%74%70%61%73%73」という文字列にしている。%xx〜というのが続いているのは、みなさんクリックし慣れているんじゃないでしょうか?これをクリックさせることに、攻撃者はユーザを強制的に攻撃者のアカウントでログインしている状態にもっていくことができる。

そして、攻撃者はあらかじめ、登録情報を空っぽ、もしくは明らかにテストデータだとわかる文字列に全て置き換えておく。

アクセスしたユーザは、うっかり登録情報を入力してしまい、後で攻撃者が自分のアカウントでログインすると情報が手に入るわけだ*5

例え、すぐに登録情報を入手できなくとも、オートログイン機能をつけているWebアプリケーション(例えばmixiみたいなの)であれば、ユーザを混乱させることは必至だと思われる。メールからのリンクだけでなく、正常遷移(例えばお気に入りとか)がらアクセスした場合も攻撃者のアカウントでログインしている状態が継続してしまう。

たぶん。明示的な「ログアウト」機能が無く、ログイン状態時はログインフォームが表示されないような作りの場合、路頭に迷うだろう。

こんなのに引っ掛かる人いるの?

フィッシングが成り立ってる現状があるので、正規のサイトにアクセスして、httpsの場合、証明書も正しいわけなので、引っ掛かる人は結構いるんじゃないかなと。

しかも、Webアプリケーションの作りによって引き起こされ、Webアプリケーションを介して情報が漏洩しているので、ユーザに難癖を付けられた時にめんどくさそうだ。

対策

ログインフォームを表示する画面からセッション管理を始めて、ログイン実行画面でもセッションIDやワンタイムトークンをhiddenに埋め込んでおけばいいんじゃない?

ただ、これをやると、うっかりSessionFixiationの脆弱性を作りこんじゃうかもなので、ちゃんとログイン成功時には、セッションIDを付け替えることをしないとダメですね。そのうちSessionFixiationについても書きたいよ。

でも、こんなことをしてるWebアプリケーションは見たこと無いですよ。ってことは、コレが被害あるんじゃん?ってなったらほとんどのサイトがダメってことになっちゃいますけど。。。

参考にしたサイト

後は、日々勉強したとこから創造。

・・・やっぱ頭悪いかなぁ?

*1:ロボットへの対策とCSRFへの対策は同じである必要は無い。コメントスパム等は、CAPTCHAを使ったりするのが有効だろう。人によるコメントスパム機械的には対処できないと思う

*2:お勧めはしないが、hiddenでパスワードを埋めても対策になるといえばなる。けど、余計に考えることが増える

*3:リファラはなんか色々挙動に癖があるので、別の問題が発生するかもよ

*4:フィッシングのプロじゃないので、これで引っ掛かる文言かどうかは知らず。

*5:パスワードの入力を求める作りの場合、当然ユーザは攻撃者のパスワードを知らないので、登録情報変更が完了できない