【问题标题】:How does this stop mass assignment?这如何停止批量分配?
【发布时间】:2011-09-19 04:23:24
【问题描述】:

我想开始在我的模型中使用 attr_accessible 来解决质量分配问题。我了解它的工作原理,并已尽我所能进行了研究。

我不明白的是使用 update_attributes(params[:my_form]) 或 create(params[:my_form]) 并一一设置字段之间的区别?不是都一样脆弱吗?

没有 attr_accessible 和这样做有什么区别...

@model_object = ModelObject.new
@model_object.create(params[:model_object_params])

并且拥有 attr_accessible 并执行此操作...

@model_object = ModelObject.new
@model_object.field1 = params[:model_object_params][:field1]
@model_object.field2 = params[:model_object_params][:field2]
@model_object.field3 = params[:model_object_params][:field3]
@model_object.save!

难道这两种创建记录的方法都同样容易受到攻击吗?黑客/破解者可以向这两种方法发送一个 url,并且两者都会做同样的事情,对吧?

或者使用 attr_accessible 并逐个更新字段会做不同的事情或以某种方式变得更安全?

我发现所有这些使用 attr_accessible 的方法对我来说都没有任何意义。它似乎以两种不同的方式做同样的事情。我错过了什么?

谢谢。

【问题讨论】:

    标签: ruby-on-rails mass-assignment


    【解决方案1】:

    批量分配不是你阻止的,而是你控制的。这是一个很好的功能,它使事情变得更容易和更清洁,但是如果没有某种能力来控制通过批量分配设置的内容,这是一个潜在的安全漏洞。正如其他人所提到的,attr_accessible 提供了这种控制。

    【讨论】:

      【解决方案2】:

      以你的方式,它不会阻止“批量分配”。

      “批量赋值”是 Rails 处理模型中属性的值分配时使用的术语。这通常在控制器中完成,使用 params 中的名称和值。

      当您自己分配时,在某种程度上也是“批量分配”;但是在这种情况下,您可以很好地控制分配什么和不分配什么。因此,为了节省编写样板分配代码,Rails 提供了attr_accesible - 相同的控制,更少的代码。

      看看它是如何使用的:

      假设ActivityLog 模型有一个名为user_ip_address 的属性。

      现在,user_ip_address 是模型中的一个属性,可以通过 mass-assignment 或“self-rolled-mass-assignment”进行分配。

      但在这两种情况下都是错误的——您不希望用户提供的输入为该属性设置值。

      相反,您希望始终找出用户的实际 IP 地址并分配该值(忽略任何 params 中的值)。因此,您将从attr_accessible 中排除user_ip_address,而是自己分配它。

      attr_accessible :all_attributes_except_user_ip_address
      
      @al = ActivityLog.new(params[:model_object_params])
      @al.user_ip_address = get_origin_user_ip_address
      @al.save
      

      对于用户不应更改的任何信息,请使用attr_accessible 并将其从列表中排除。

      【讨论】:

      • 哦,我明白了,所以我正在做的事情会阻止诸如 created_by 或 creator_id 字段的设置,但如果没有更好的控制,正在发送和我正在分配的字段仍然可能有恶意数据。这就是让我发疯的地方。所有这些示例基本上只是手动分配每个字段,而不是通过传递参数哈希。现在我明白了,谢谢。
      【解决方案3】:

      简短的回答是它会阻止 field4 被隐式设置。

      不同之处在于,如果没有attr_accessible,黑客可以更新不在您的表单中的字段。 attr_accessible 这不可能。

      例如如果您的用户模型有一个字段is_admin,黑客可能会尝试通过发布来创建新管理员:

      params[:user][:is_admin] = true
      

      如果设置了attr_accessible(显然它不应该包含is_admin)这是不可能的。

      关于您的示例:如果您的模型只有field1field2field3,并且没有要保护的其他数据库列,则无需使用attr_accessible。希望这说明清楚。

      记住:

      没有任何预防措施 Model.new(params[:model]) 允许 攻击者设置任何数据库列的 价值。

      来源:http://guides.rubyonrails.org/security.html#mass-assignment

      【讨论】:

        【解决方案4】:

        这里的想法是限制您将为给定模型接受的参数。然后,您可以使用验证或其他代码对它们中的每一个进行测试,以确保它们符合预期值。

        Attr_accessible 旨在将模型的“表面”限制在您打算接受和仔细检查的范围内。通过这种方式,您可以自动忽略注入的参数,例如 :roles => "admin",以防您将该功能添加到模型中

        user.update_attributes(params[:user])
        

        由于attr_accessible中没有列出roles属性,所以用户尝试成为管理员是没有结果的。

        您希望在一个地方(您的模型)处理验证逻辑,而不是检查控制器中的每个参数值。

        【讨论】:

          猜你喜欢
          • 2021-09-05
          • 1970-01-01
          • 2011-11-18
          • 1970-01-01
          • 1970-01-01
          • 2021-04-12
          • 2012-07-06
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多