【问题标题】:Rails request forgery protection settingsRails 请求伪造保护设置
【发布时间】:2011-02-13 02:01:50
【问题描述】:

请帮助 Rails 中的新手 :) 我的 ApplicationController 类中有 protect_from_forgery 调用(默认情况下),但没有属性。

基本上是代码:

class ApplicationController < ActionController::Base
  helper :all # include all helpers, all the time
  protect_from_forgery
  helper_method :current_user_session, :current_user
  filter_parameter_logging :password, :password_confirmation

我认为它应该做的是:它应该阻止任何没有正确authenticity_token 的 POST 请求。但是当我像下面这样使用 jQuery 发送 post 请求时,它工作正常(数据库中执行了更新语句)!

$.post($(this).attr("href"), { _method: "PUT", data: { test: true } });

我在控制台中看到发送的参数中没有authenticity_token,但请求仍然被认为是有效的。这是为什么呢?

UPD 在 config/environments/development.rb 中找到配置设置

config.action_controller.consider_all_requests_local = true

由于DEV环境和本地请求,这些jQuery post请求都OK。

【问题讨论】:

    标签: ruby-on-rails request authenticity-token protect-from-forgery


    【解决方案1】:

    也许是个愚蠢的问题:您确定要继承 ApplicationController 吗?你的路线图是什么样的?什么版本的 Rails(只是为了清楚起见)?

    您是否验证了来自 jQuery 的调用实际上是 POST 而不是 GET? (我知道,这似乎很明显)。 Rails 只会对非 GET 请求执行保护。

    另外,发出的请求的 content-type 是什么。根据the docs,Rails 也只会执行保护,前提是它是一个 HTML/Javascript 请求。

    【讨论】:

    • 实际上,查看verified_request 的来源? (Rails 使用它来验证真实性令牌)似乎如果请求是 xhr 则它不会注意身份验证令牌。 也许 jQuery 将 content-type 设置为让 Rails 认为它​​正在响应 xhr 请求并忽略缺少 auth 令牌的东西?
    • 感谢您的回复!是的,我肯定继承了 ApplicationController(实际上,我继承了 AdminController 的子类,即 ApplicationController 的子类)。是的,这是根据“development.log”文件的 POST/PUT 请求。我还在那里看到了所有 POST 请求参数,并且没有authentity_token。即使在默认 jQuery contentType 的情况下,它不应该引发异常吗?!
    • 你确定如果是xhr请求,那么Rails不会关注auth token吗?这不是坑吗?
    • 代码说如果request.xhr? 为真,它将忽略(缺少a)令牌。如果你logger.debug request.xhr?,它说什么?如果这是真的,那么 Rails 将忽略身份验证令牌,您将不得不使用 contentType。这似乎是一个安全漏洞。要在此处修补它,您可以拒绝任何 xhr 请求。
    • 老实说,我不认为这是真的:互联网上有很多关于如何将身份验证令牌添加到 jquery 发布请求的讨论(比如这个 - brandonaaron.net/blog/2009/02/24/jquery-rails-and-ajax)。没有令牌它不起作用。一定是别的原因,可能是因为 Paddy 建议的本地电话。
    【解决方案2】:

    只要在应用程序内部执行请求 $.post($(this).attr("href"), { _method: "PUT", data: { test: true } });,您的代码就没有问题。如果您在其他地方运行了另一个应用程序,例如在 localhost:3001 上,并且您从那里发送了一个帖子,那么它将无法工作。事实上,如果你使用的是 firefox > 3.0,它也有一个跨站点 xhr 的早期实现。例如,您可以从任何其他站点发送 POST(但前提是保护_from_forgery 已关闭!)。 xhr 不需要 auth token 的原因是禁用了跨站点 xhr。因此在不提供身份验证令牌的情况下使用 xhr 是安全的。如果您从应用程序以外的任何其他地方尝试,我相信它会引发异常,要求提供身份验证令牌。此外,您应该定义一个 crossdomain.xml 以防止来自外部来源的访问。

    尝试这样做:curl -X -d url_endpoint_of_your_app。看看您是否收到 200 响应代码。如果你这样做了,那就有问题了。

    【讨论】:

    • 我认为即使从另一个应用程序也不应该从 localhost 完成。我会检查,可能你是正确的,这被认为是本地呼叫,没有任何额外的安全检查。
    • 即使您从 localhost 执行操作,它也会在不同的端口上运行。因此,应用程序从不同的域运行。唯一的解决方案是修改 crossdomain.xml
    • 太棒了。我找到了 DEV env 的设置,可以对其进行修改以更改此行为。
    • 您能否也与我们所有人分享您的发现。 :)
    猜你喜欢
    • 2018-04-25
    • 2016-02-29
    • 2019-04-10
    • 2013-01-11
    • 2021-10-17
    • 1970-01-01
    • 2014-06-21
    • 2013-08-05
    • 1970-01-01
    相关资源
    最近更新 更多