Mongoid:如何防止通过批量分配创建未定义的字段?

发布于 2024-12-11 14:31:52 字数 842 浏览 0 评论 0原文

代码如下:

class M
  include Mongoid::Document
  field :name
end

params = { name: "foo", age: 20 }
M.create(params)
#=> #<M name: "My Name", age: 20>

请注意,age 尚未定义,但已保存。

这是有问题的(可能是 DoS 的来源),因为恶意用户可以在 POST 中添加任何参数,并且带有大字符串的未知字段可能会潜入。(例如 name=foo&bogus=#{'x'*1000000}

到目前为止,我除了 attr_accessible 之外找不到任何东西,但这对于 Mongoid 来说并不是很好,因为你必须在两个中维护相同的字段名称在所有模型中,fieldattr_accessible 始终存在。不干。

我认为 attr_accessible API 非常适合 ActiveRecord,因为 a. 您无需在模型 (DRY) 和 b. 中显式定义字段> 保证不存在的字段不会被保存到 RDB 中。但对于 Mongoid,我认为应该有比 attr_accessible 更好的解决方案。

请注意,有一个全局配置设置 allow_dynamic_fields 但它与质量分配无关,因此超出了本讨论的范围,但我认为它实际上应该是每个模型的宏,并且还应该处理质量-任务。

你是如何处理这个问题的?

Here's the code:

class M
  include Mongoid::Document
  field :name
end

params = { name: "foo", age: 20 }
M.create(params)
#=> #<M name: "My Name", age: 20>

Notice that age wasn't defined, yet it was saved.

This is problematic (potentially a source of DoS) because a malicious user can add any parameters in POST and unknown fields with a large string can sneak in. (e.g. name=foo&bogus=#{'x'*1000000})

So far, I couldn't find anything but attr_accessible, but it's not really great for Mongoid as you have to maintain the same field names in both field and attr_accessible all the time, in all models. Not DRY.

I think the attr_accessible API is great for ActiveRecord, because there a. you don't explicitly define fields in the models (DRY) and b. it's guaranteed there's no chance that a nonexistent field gets saved to RDB. But for Mongoid, I think there should be a better solution than attr_accessible.

Note that there's a global config setting allow_dynamic_fields but it's not about mass assignment so it's out of the scope in this discussion, however I think it should actually be a per-model macro and should also take care of mass-assignment.

How are you dealing with this problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

愿与i 2024-12-18 14:31:52

我总是在模型中使用 attr_accessible 。我很少发现自己把所有领域都纳入了可及的范围。通常总是有一些字段不应该被批量分配访问。如果您经常需要包含每个属性并且担心重复:

attr_accessible *fields.keys

I'm always using attr_accessible in models. I rarely found myself including all fields as accessible. Usually there are always a few fields that shouldn't be accessible for mass assignment. If you often need to include every attribute and you're concerned about duplication:

attr_accessible *fields.keys
番薯 2024-12-18 14:31:52

我为解决这个问题所做的就是在我的模型中使用保存前回调:

set_callback(:save, :before) do |doc|
    (doc.attributes.keys - fields.keys).each { |f| doc.unset(f) }
end

这样,即使有额外的属性,它们也会在保存之前被删除。

What I have done to solve this issue, is use a before save callback in my model:

set_callback(:save, :before) do |doc|
    (doc.attributes.keys - fields.keys).each { |f| doc.unset(f) }
end

This way, even if there are extra attributes they get removed before being saved.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文