CSRFトークンの検証プロセス

actionpack-3.2.2/lib/action_controller/metal/request_forgery_protection.rb

line:67

def protect_from_forgery(options = {})
  self.request_forgery_protection_token ||= :authenticity_token
  prepend_before_filter :verify_authenticity_token, options
end
  • protect_from_forgeryはデフォルトでApplicationControllerで宣言されている。
  • verify_authenticity_tokenをすべてのアクションの前に実行するようになる。

line:72

def verify_authenticity_token
  unless verified_request?
    logger.warn "WARNING: Can't verify CSRF token authenticity" if logger
    handle_unverified_request
  end
end

line:84

def handle_unverified_request
  reset_session
end
  • verified_request?falseの場合はセッションがリセットされる。

line:93

def verified_request?
  !protect_against_forgery? || request.get? ||
    form_authenticity_token == params[request_forgery_protection_token] ||
    form_authenticity_token == request.headers['X-CSRF-Token']
end
  • params[request_forgery_protection_token]protect_from_forgeryの中で定義されている通りparams[:authenticity_token]になる。
  • params[:authenticity_token]はformヘルパーが自動生成するhiddenフィールドから送信される。
  • params[:authenticity_token]がない場合でも、HTTPヘッダーのX-CSRF-Tokenを設定すればいい。

line:100

def form_authenticity_token
  session[:_csrf_token] ||= SecureRandom.base64(32)
end
  • params[:authenticity_token]またはrequest.headers['X-CSRF-Token']session[:_csrf_token]と一致しているかどうかが、CSRFトークンの検証の本体である。