Rails 2.0でCSRF対策
Rails 2.0ではCSRF(cross site request forgery, クロスサイトリクエストフォージェリ)対策が標準で入っているって事でActionController::RequestForgeryProtection::ClassMethodsのRdocを読みながら試した。まず、以下の様なコントローラ(top_controller.rbとした)を作る。
Railsアプリのルートで
./script/generate controller top index
(だっけ?)
top_controller.rbの中身は以下の通り。
class TopController < ApplicationController protect_from_forgery :secret => 'my-little-pony', :only => :index def index end end
キモはprotect_from_forgeryだけらしい。さらに、対応するindex.html.erbは以下の様な感じで作成。
<% form_tag :action=>'index' do %> <%=submit_tag 'OK' %> <% end %>
保存したら、サーバを立ち上げてアクセスしてみる。
OKボタンだけがあるページが表示されるが、ソースを見ると
<form action="/" method="post"> <div style="margin:0;padding:0"> <input name="authenticity_token" type="hidden" value="1995ed1a2b957522850d27f1aa473cae6e90cf1b" /> </div> <input name="commit" type="submit" value="OK" /> </form>
というHTMLが生成される。hiddenフィールドとして、tokenが入っている。ブラウザを立ち上げ直すとauthenticity_tokenのinputタグのvalueは変化しているのでセッション単位かな?submitしてもリロードしても、この値は変わらないみたい。
ここでちゃんとtokenが検証されていることを確認するためにFirefoxにFirebugアドオンをインストールして、フォームのtokenを編集してみてsubmitすればちゃんと以下のエラーが発生。
ActionController::InvalidAuthenticityToken in TopController#index
というわけで、コントローラにprotect_from_forgeryを追加する以外には特にすることはなさそうだ...すごく簡単...しかもオフィシャルなので最低限の安心感はある...採用(即決)
空気読めないけどそれなりに働いているyotenaでした。
(追記)ちなみに:secretの部分は秘密のランダム推奨だと思います。