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/