6

我想开始在我的模型中使用 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 的方法对我来说没有任何意义。它似乎以两种不同的方式做同样的事情。我错过了什么?

谢谢。

4

4 回答 4

7

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

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

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

要查看它是如何使用的:

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

现在,user_ip_address是模型中的一个属性,可以通过质量分配或“自滚动质量分配”进行分配。

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

相反,您希望始终找出用户的实际 IP 地址并分配该值(忽略 中的任何值params)。所以你会排除它user_ip_addressattr_accessible而是自己分配它。

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并将其从列表中排除。

于 2011-06-21T03:47:24.320 回答
3

简短的回答是它不再field4被隐式设置。

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

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

params[:user][:is_admin] = true

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

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

只要记住:

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

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

于 2011-06-21T03:38:06.977 回答
2

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

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

user.update_attributes(params[:user])

由于角色属性未在 attr_accessible 中列出,因此用户尝试成为管理员是徒劳的。

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

于 2011-06-21T03:37:17.940 回答
2

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

于 2011-06-21T04:21:35.873 回答