CSRF token 不匹配时,Rails会引发InvalidAuthenticityToken。但是,通过阅读source,我无法弄清楚这是如何发生的。我从确认该类的树开始:

$ ack --ignore-dir=test InvalidAuthenticityToken

actionpack/lib/action_controller/metal/request_forgery_protection.rb
4:  class InvalidAuthenticityToken < ActionControllerError #:nodoc:
17:  # which will check the token and raise an ActionController::InvalidAuthenticityToken

actionpack/lib/action_dispatch/middleware/show_exceptions.rb
22:      'ActionController::InvalidAuthenticityToken' => :unprocessable_entity

只有两个命中,忽略了评论。第一个是类定义:
class InvalidAuthenticityToken < ActionControllerError #:nodoc:
end

第二个是将异常转换为HTTP状态代码。通过在 Controller 中调用protect_from_forgery来启用CSRF保护,因此让我们看一下:
def protect_from_forgery(options = {})
  self.request_forgery_protection_token ||= :authenticity_token
  before_filter :verify_authenticity_token, options
end

它添加了一个过滤器:
def verify_authenticity_token
  verified_request? || handle_unverified_request
end

验证失败时,哪个调用此方法:
def handle_unverified_request
  reset_session
end

那么InvalidAuthenticityToken实际如何提高?

最佳答案

行为是changed fairly recently,但是文档尚未更新。使用的新方法是假定 session 已被劫持,因此清除 session 。假设您的 session 包含此请求的所有重要身份验证信息(例如您以alice登录的事实),并且您的 Controller 确保用户已针对此操作进行了身份验证,则您的请求将被重定向到登录页面(或选择处理非登录用户)。但是,对于未认证的请求(例如注册表单),该请求将使用空 session 进行。

似乎此提交也继续关闭了CSRF vulnerability,但我没有详细阅读。

要获得旧的行为,只需定义以下方法:

def handle_unverified_request
  raise(ActionController::InvalidAuthenticityToken)
end

您可以在Ruby on Rails Security Guide上阅读有关CSRF和其他Rails安全问题的更多信息。

关于ruby-on-rails - Rails CSRF保护如何工作?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5000333/

10-11 01:36
查看更多