2011-02-15 72 views
20

当CSRF令牌不匹配时,Rails引发InvalidAuthenticityToken。但是,从阅读source,我无法弄清楚这是如何发生的。我从acking那棵树开始:Rails CSRF保护如何工作?

$ 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状态代码。 CSRF保护得到由控制器调用protect_from_forgery启用,所以让我们看看:

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实际上是如何提升的?

回答

21

行为是changed fairly recently但文档尚未更新。正在使用的新方法是假定会话已被劫持,因此要清除会话。假设你的会话包含这个请求的所有重要的认证信息(例如你登录为alice的事实),并且你的控制器保证用户通过了这个动作的认证,你的请求将被重定向到一个登录页面(或者你选择处理未登录的用户)。但是,对于未通过身份验证的请求(如注册表单),请求将使用空会话。

看来这个提交也继续关闭CSRF vulnerability,但我没有读到细节。

为了得到旧的行为,你会简单地定义这个方法:

def handle_unverified_request 
    raise(ActionController::InvalidAuthenticityToken) 
end 

你可以阅读更多关于CSRF等Rails的安全问题在Ruby on Rails Security Guide

+0

谢谢!这就是我运行3.0.3但读取master的源代码所得到的结果。对这一变化背后原因的很好解释 - 甚至比官方博客文章中的更好。 – 2011-02-15 23:45:22

9

verify_authenticity_token曾经被定义为

verified_request? || raise(ActionController::InvalidAuthenticityToken) 

但正如你提到的,现在叫handle_unverified_request,进而调用reset_session

我不认为Rails的实际抛出的异常了。

http://weblog.rubyonrails.org/2011/2/8/csrf-protection-bypass-in-ruby-on-rails状态

应用这个补丁失败后CSRF 请求将不再生成HTTP 500错误,而不是会议将 复位。用户可以通过在其自己的 控制器中重写 handle_unverified_request来覆盖此行为。

https://github.com/rails/rails/commit/66ce3843d32e9f2ac3b1da20067af53019bbb034

+0

谢谢!我希望我能接受这两个答案。 – 2011-02-15 23:48:04