【问题标题】:CSRF protection when migrating from Rails 3 to Rails 4从 Rails 3 迁移到 Rails 4 时的 CSRF 保护
【发布时间】:2018-11-13 00:48:56
【问题描述】:

我正在将一个大型网站包从 Ruby 1.9 迁移到 Ruby 2.3,我几乎完成了。我已经让 Rails 几乎完全从 3.2 迁移到 4.2,但是我遇到了一个我无法弄清楚的问题,这个项目是我第一次使用 Ruby 或 Rails,所以我一直在使用术语作为我去。

当我将浏览器指向我的开发服务器时,我所有的 GET 请求都成功 (200),但我所有的 POST 请求都失败了 (500)。经过一番研究,我发现了 Rails 内置的 CSRF 保护,并且能够确定我正在使用的包在使用 Rails 3.2 时具有这种保护。

有了 Rails 4.2,保护似乎阻止了任何 POST 请求成功。在进一步研究之后,我发现 Rails 4 在将 auth cookie 发送到 Web 服务器之前对其进行加密,而 Rails 3 没有,并且在所有用户都使用 Rails 4 之前使用 Rails 3 cookie 是一个好习惯。我注释掉了我在迁移过程中创建的 secret_key_base 定义,并清除了浏览器缓存,所以据我了解,我现在应该使用未加密的 Rails 3 cookie。

但是,我的 POST 请求仍然抛出 500s。我不能分享太多代码,但我引用了this official guide,我的应用程序控制器中确实有这一行:

protect_from_forgery with: :exception

我也验证了如果我注释掉保护和使用:

skip_before_action :verify_authenticity_token

那么 POST 请求就会成功(它们只是非常不安全)。

我读过的大部分内容似乎表明此功能取决于我在上面显示的protect_from_forgery 行,仅此而已。

我似乎无法让这些请求成功,我想知道这是否只是我尚未掌握的另一层知识。非常感谢任何帮助。

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-4


    【解决方案1】:

    你的应用布局,大概app/views/layouts/applications.html.erb需要参考<%= csrf_meta_tags %>

    这是所有表单帖子中包含和检查的内容。

    如果您没有在所有视图中使用该布局,则需要找出另一种方法来确保它在任何地方都被引用。

    Docs

    【讨论】:

    • 在那个目录中我没有任何 .erb 文件,但我有 application.haml,它以:%html %head = csrf_meta_tags 开头标记语言?
    • 是的,这意味着您使用的是haml 而不是erb,它应该不会对错误产生任何影响
    • 您好,感谢您的评论。澄清一下,你的意思是如果我使用 haml 它将无法正确启用 csrf 保护?或者你的意思是我可以使用其中任何一个并且它应该可以工作?在第二种情况下,这些 POST 请求失败是否还有其他原因?谢谢!
    • 我猜还有一个问题,将这个元标记放在 application.haml 文件中的 %head 下是否使它可以在任何地方被引用?还是我仅将其应用于我的包裹的一个子集?在我看来,这个设置将适用于全球,但想仔细检查。在这种情况下,为什么还会出现这个问题?
    • 看来这不是你的问题,所以我会寻找其他地方,可能是另一个答案中提到的config/secrets.yml 文件。
    【解决方案2】:

    你有config/secrets.yml 文件吗?它应该看起来像这样:

    development:
      secret_key_base: a75d...
    
    test:
      secret_key_base: 492f...
    
    production:
      secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
    

    如果是这样,您需要确保您的服务器设置了环境变量。需要小心处理密钥,并且永远不要将其提交给公共存储库,即 GIT。

    参考https://guides.rubyonrails.org/v4.2/security.html

    【讨论】:

    • 抱歉发布得太早了。当我有足够的信息时会更新。
    • 好的,我对此有疑问。在我的 Web 服务器的日志中,我看到了这个警告:请注意,您应该等待设置 secret_key_base,直到您在 Rails 4.x 上拥有 100% 的用户群并且有理由确定您不需要回滚到 Rails 3.x .这是因为基于 Rails 4.x 中新的 secret_key_base 签名的 cookie 不能向后兼容 Rails 3.x。您可以随意保留现有的 secret_token,不设置新的 secret_key_base,并忽略弃用警告,直到您有理由确定升级已完成。
    • 我认为这意味着在我们向整个用户群推出此升级并验证没有任何问题之前,我们需要注释掉secret_token.rb 并继续使用 secret_token 定义。这是否意味着在我的 secrets.yml 文件中,我应该改用: development: secret_token ?
    • 尝试用 secret_token 替换 secrets.yml 中对 secret_key_base 的引用,但 POST 仍然失败 (500)。
    猜你喜欢
    • 1970-01-01
    • 2011-07-30
    • 2012-01-28
    • 1970-01-01
    • 2010-12-22
    • 2015-05-03
    • 1970-01-01
    • 2014-07-31
    • 1970-01-01
    相关资源
    最近更新 更多