大量の「はまちちゃん」を生み出したCSRFの脆弱性とは? (ITmedia)

「クロスサイト・リクエスト・フォージェリ(Cross Site Request Forgeries:CSRF)」と言うらしい。手法自体は昔拙著でも書いていて、当時はそんな言葉なかったので「自動投稿攻撃」などとセンスのない名称で言ってたやつです。横文字だとなんか難しげでカッコイイね。

そもそもこの脆弱性って、CGIライブラリやWebアプリケーションフレームワークの多く(Strutsにしても、PerlのCGI.pmにしてもPHPにしても)がGETとPOSTの違いを隠蔽して同等に扱えちゃうのが根源だと思うけど…。

そう、第一の対策はPOSTメソッドのみ受け付けるようにすること。GETとPOSTの使い分けなんて、どんなサイトでも必須であって、やってないのは問題外(やってなかったのかよmixi)。でもこれだとJavaScriptを使ってPOSTメソッドを生成されてしまうケースがあるので完全ではない。

なお「HTTP Refererをチェックするという方法も考えられるが、中にはHTTP Refererを出力しないブラウザも存在する」(中村氏)ため、前述した方法が推奨されるということだ。(ITmedia)

理想的にはその通り。確かに一部のブラウザではRefererは出力されなかったり、プロキシによってカットされちゃうケースもある。けど、CSRFは外部からの攻撃ではなく、自分でリンクを踏んで攻撃しちゃうってやつなので、実質的にはRefererチェックだけでも十分効果あると思っています。ただし「Refererヘッダが来ている場合だけ」チェックすること。そうしないと一部の環境から機能が使えない状態になってしまう。もちろんGETメソッドを弾くのは必須。

しかし、より効果的な対策法であるワンタイムトークンは、CSRFの防御のみならず、遷移制御やSubmitボタン連打防止にも役に立つので、ライブラリとして持っておいたほうが何かと便利だと思われます。理想的にはワンタイムトークンをプログラマがほとんど無意識で使えるような仕組みがフレームワーク的に整っていれば、CSRF脆弱性に対しても、不正な遷移に対しても自然に防御できるようになると思われます。こういったことを考えたセキュアなWebアプリフレームワークが欲しいです。というか作りたいです。

超重要な処理では、究極は再認証(パスワード再入力など)です。Yahoo!とかでもやってますね。ただし利便性を損ねることになるので、使うべきところをきちんと考える必要があります。