CSRF防止とセッションタイムアウト

rails2系はえらい子なのでCSRFを自動的に防止してくれます。
app/controllers/application.rbに

protect_from_forgery # :secret => 'ないしょ'

とかいとくだけでget以外のときに自動的にトークンを埋め込み不正な遷移かどうか確認してくれます。なんとも出来る子です。しかし、この機能とセッションタイムアウトの設定を同時に使うとなんともエラーが発生してしまう。

この機能はaction_controller/request_forgery_protection.rbの中でセッションの中のダイジェストとクライアントから送られてきたダイジェストが同じかどうかを判断しているのですが、セッションタイムアウトが働いているとこの時点でセッションが空っぽになっている。なのでCSRFエラーとなりActionController::InvalidAuthenticityTokenが発生してしまう。

      # No secret was given, so assume this is a cookie session store.
      def authenticity_token_from_cookie_session
        session[:csrf_id] ||= CGI::Session.generate_unique_id
        session.dbman.generate_digest(session[:csrf_id])
      end

どちらかというとこの評価は後にしてちゃんとセッションタイムアウトエラーを出したいな〜とおもってみていたらRoRWikiによさげな記事があった
http://techno.hippy.jp/rorwiki/?HowtoChangeSessionOptions

んでこんなのを書いてbefore_filterの権限管理の前に入れてみたところセッションタイムアウトはちゃんと実施されCSRFの精査もうまく行った。

def set_session_expiration
  return unless session
  reset_session if session['expiry_time'] && session['expiry_time'] < Time.now
  session['expiry_time'] = Time.now + 5.minutes
end

しかもクッキー自体の生存期間が未設定になるのでクライアントプロセス内にしか保存されないようになるのでいい
何事にも先達はあらまほしきことかな