Rails CSRF 保护是如何工作的? [英] How does Rails CSRF protection work?

查看:45
本文介绍了Rails CSRF 保护是如何工作的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Rails 在 CSRF 令牌不匹配时引发 InvalidAuthenticityToken.但是,通过阅读,我无法弄清楚这实际上是如何发生的.我首先确认该类的树:

Rails raises an InvalidAuthenticityToken when the CSRF token doesn't match. But, from reading the source, I can't figure out how this actually happens. I start by acking the tree for that class:

$ 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

只有两次点击,忽略评论.第一个是类定义:

Only two hits, ignoring the comment. The first one is the class definition:

class InvalidAuthenticityToken < ActionControllerError #:nodoc:
end

第二个是将异常转换为 HTTP 状态代码.通过在控制器中调用 protect_from_forgery 来启用 CSRF 保护,让我们看看:

The second one is translating the exception into an HTTP status code. CSRF protection gets enabled by calling protect_from_forgery in the controller, so let's look at that:

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

验证失败时调用此方法:

Which calls this when verification fails:

def handle_unverified_request
  reset_session
end

那么 InvalidAuthenticityToken 究竟是如何产生的?

So how is InvalidAuthenticityToken actually raised?

推荐答案

行为最近发生了变化文件尚未更新.正在使用的新方法是假设会话已被劫持,因此清除会话.假设您的会话包含此请求的所有重要身份验证信息(例如您以 alice 身份登录的事实)并且您的控制器确保用户已通过此操作的身份验证,您的请求将被重定向到登录页面(或者您选择处理未登录的用户).但是,对于未经身份验证的请求(例如注册表单),该请求将使用空会话进行处理.

The behavior was changed fairly recently but the documentation has yet to be updated. The new approach being used is to presume the session has been hijacked, and therefore to clear the session. Assuming your session contains the all-important authentication information for this request (like the fact you're logged in as alice) and your controller assures the user is authenticated for this action, your request will be redirected to a login page (or however you choose to handle a non logged-in user). However, for requests which are not authenticated, like a sign-up form, the request would go through using an empty session.

似乎此提交还继续关闭 CSRF漏洞,但我没有仔细阅读它的细节.

It seems this commit also goes on to close a CSRF vulnerability, but I didn't read into the details of that.

要获得旧行为,您只需定义此方法:

To obtain the old behavior, you would simply define this method:

def handle_unverified_request
  raise(ActionController::InvalidAuthenticityToken)
end

您可以在 Ruby on Rails Security 中阅读有关 CSRF 和其他 Rails 安全问题的更多信息指南.

这篇关于Rails CSRF 保护是如何工作的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆