【问题标题】:protect_from_forgery - does order matter?protect_from_forgery - 顺序重要吗?
【发布时间】:2018-01-09 00:11:30
【问题描述】:

我已经阅读了这篇https://nvisium.com/blog/2014/09/10/understanding-protectfromforgery/ 的帖子,如果我理解正确,默认情况下在 Rails 3 中,如果我们有一个看起来像这样的控制器:

class ApplicationController < ActionController:Base
  protect_from_forgery
end

最终会发生的是(在攻击者的情况下)会话将被破坏。这意味着如果我们做一些检查用户是否经过身份验证的事情,因为没有会话,它将停止请求。

所以,我的问题是,我相信:

class ApplicationController < ActionController:Base
  protect_from_forgery
  before_action :authenticate_user

  private

  def authenticate_user
    raise NotAuthenticated unless session.key?(:user)
  end
end

是正确的做法,而不是

class ApplicationController < ActionController:Base
  before_action :authenticate_user
  protect_from_forgery

  private

  def authenticate_user
    raise NotAuthenticated unless session.key?(:user)
  end
end

或者换句话说,protect_from_forgery 应该是我们在控制器中做的第一件事。

我的假设是否正确,或者我在控制器中的操作顺序如何工作方面遗漏了一些东西?

【问题讨论】:

    标签: ruby-on-rails csrf csrf-protection


    【解决方案1】:

    这两种方法的顺序并不重要,不。

    原因与 when 这些方法被执行有关:这些是类级别的方法,当 Ruby 加载文件时在类本身的上下文中执行。

    查看protect_from_forgery的来源:

    def protect_from_forgery(options = {})
      options = options.reverse_merge(prepend: false)
    
      self.forgery_protection_strategy = protection_method_class(options[:with] || :null_session)
      self.request_forgery_protection_token ||= :authenticity_token
      before_action :verify_authenticity_token, options
      append_after_action :verify_same_origin_request
    end
    

    这些基本上是在调用它们时将代码添加到您的类的宏,这是一种元编程形式。您可以将类中的方法调用替换为手动设置这些内容,并且是相同的。

    这一切都发生在您的代码第一次加载时,在应用程序启动之前。

    【讨论】:

    • 感谢您的回答。我仍然不明白如果我想先执行protect_from_forgery,然后验证会话中的任何内容,这将如何工作。如果我反过来做,删除会话也没关系,因为攻击者可能已经使用了它。
    • 防伪和用户身份验证是不同的关注点。执行它们的顺序无关紧要,因为无论在响应请求之前会发生什么。
    • 我知道它们会在请求得到响应之前发生。但是,如果用户身份验证发生在伪造保护之前(会话被删除),我们会认为用户已正确验证,因为当它到达时我们仍然有会话。有意义吗?
    • 如果会话在响应过程中被删除,那么它将表现为用户未通过身份验证。在此期间没有机会使用会话。至少它应该是这样工作的,因为您没有提供任何身份验证代码,我只能笼统地说。
    • 我添加了一些虚拟代码来表示我的意思。它不一定需要与身份验证有关,但对我来说是任何依赖于会话的代码。如果我们在会话使用后删除它,那么我们可能会遇到麻烦。这就是为什么我希望protect_from_forgery 应该是在控制器中的任何操作之前执行的第一件事。
    猜你喜欢
    • 2014-08-06
    • 1970-01-01
    • 1970-01-01
    • 2017-11-18
    • 2012-06-27
    • 2010-09-07
    • 1970-01-01
    • 2016-10-24
    相关资源
    最近更新 更多