ruby-on-rails - Rails CSRF 保护是如何工作的?

标签 ruby-on-rails ruby ruby-on-rails-3

当 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/

相关文章:

ruby-on-rails - 使用 Postmarkapp 在 Rails 应用程序中处理电子邮件异常的最佳方法是什么?

ruby-on-rails - 在设计注册表单中使用参数

ruby-on-rails - 在 ActionMailer 中使用助手

ruby-on-rails - 如何使用 Ruby on Rails 转换字符串 `to_json` 和 `to_xml`?

ruby-on-rails - 单表继承和 ActiveRecord 关联

ruby-on-rails - 为什么 ERB 会出现此错误?

ruby-on-rails - has_one 关联 rails 上保存了多个条目

ruby-on-rails - 对模型使用 has_and_belongs_to_many 是个坏主意吗?

ruby - DataMapper 多对多删除约束

ruby-on-rails - 双命名空间路由问题