2012年08月27日

正しいCSRF対策のまとめ2012年版

CSRFに関する冤罪疑惑がニュースになっていることもあり、まとめてみようと思う。

まずCSRFとXSSの違いは、攻撃者がユーザに好きなコードを実行させることが出来る点にある。
XSSはWebサーバの管理者が正しくテンプレートを使ってHTMLとjavascriptをクオートし、文字エンコードを正しく設定し、IEのバグにさえ注意すれば大体は防げる。現在発生するのは単にコード上の不注意によるバグか、ブラウザ側のバグが多い。
もちろん大いに神経を使って対策スべき事柄であることには違いがないが。

一方CSRFは攻撃者のサーバとユーザの通信から始まるので、中間者攻撃と似た多様な攻撃手段になりうる。

CSRFの目的は
  1. ユーザーの秘密情報を奪うこと
  2. ユーザーに不適切な行動を起こさせること
  3. 2によってサーバーに被害を与えること
がある。

そしてその手段としては
  1. iframeとjavascriptによってGETやPOSTをユーザーのクリックなしにエミュレートする
  2. cssで偽装したiframeによって、ユーザーが意図しないクリックを行うよう誘導する
  3. scriptタグによってJSONや部分的にjavascriptとして解釈可能なページを(攻撃者のサイトのページ内に)読み込む
  4. flashなどを使ってヘッダをエミュレートしたリクエストをブラウザ経由で行う
がある。 他の手法はほとんどブラウザ側のsameoriginポリシー(ほかドメインに対するjavascriptでのajax要求は禁止される)で排除されるはずである。

これら全てを回避する方法として
  • 何らかの処理を起動するような、ユーザのクリック(=意思あるいは同意)を確認すべき全ての画面遷移とその前後で(ログインパスワード入力フォームを含む)で、ワンタイムトークンを発行・検証する。
  • ワンタイムトークンはformのhidden要素などとしてページ内に埋め込む。cookieなどブラウザグローバルなローカルストレージに格納してはならない
  • ワンタイムトークンは、ログインクッキーなどで判別したユーザーと一致すること必ず確認する
  • X-frame-options: deny (あるいはsameorigin)ヘッダを設定する
  • JSONなどjavscriptとして解釈されうるページに秘密情報を載せたりJSONPへのアクセスを破壊的操作に利用しない。
を必要条件としてするべき。
また実装上の提案として
  • ウェブアプリは多タブでのアクセスを前提として、操作はタブごとにトランザクション管理するか、多タブ表示を検出して一方をロック出来るよう実装する。
  • ワンタイムトークンがユーザーの正しい使い方でも使いまわされる可能性があることを認識し、ワンタイムトークンの再発行手段を用意しておく
ことが望ましい。それについてはhttp://causeless.seesaa.net/article/288497459.html に書いた。

対策の根拠を解説する。

  • 攻撃者がユーザーとウェブアプリとの間で交される秘密情報を一切入手できないことを保証しなければならない。
これは、JSONPに秘密情報を載せないこととブラウザ側のSameoriginポリシーによって保証出来る。

  • 攻撃者がユーザーのSubmitクリックを偽装できないことを保証しなければならない。
これは、ページ単位のトークン(攻撃者が読めないので次のページにトークンを含めることはできない)と、X-frame-options: denyに(ユーザの意図しないクリックを発生させない)よって保証される。

  • そのほか。
徳丸先生が言っているように、ログイン済みでないユーザを誘導してクリックさせる行為はCSRFに近いがCSRFではない。
ただし、ログインフォームをclipped iframeで偽装してユーザーにクリックさせ、ブラウザに保存済みのパスワードを送信させる攻撃手段はあり得る。ログインすると、プライバシー情報が露出する要な場合、たとえば今どこにいるか公開されたり、インタレストマッチ広告のターゲットになる、などといったユーザーへの被害がありうるため、ログインフォームに関してはみログイン状態出会っても、対策すべきである。

この記事には特に以下の記事を参考にさせていただきました。
金床氏
徳丸浩氏の『徳丸本に載っていないWebアプリケーションセキュリティ』
http://www.slideshare.net/ockeghem/phpcondo
高木浩光氏
http://takagi-hiromitsu.jp/diary/20060409.html



posted by ko-zu at 22:27| Comment(0) | TrackBack(0) | セキュリティ | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前: [必須入力]

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
この記事へのトラックバックURL
http://blog.seesaa.jp/tb/288690661
※言及リンクのないトラックバックは受信されません。

この記事へのトラックバック
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。