rails:与belongs_to关系的大规模分配安全问题
Posted
技术标签:
【中文标题】rails:与belongs_to关系的大规模分配安全问题【英文标题】:rails: mass-assignment security concern with belongs_to relationships 【发布时间】:2011-01-10 16:09:12 【问题描述】:我一直在阅读有关 Rails 安全问题的信息,其中让我最担心的是批量分配。我的应用程序正在使用 attr_accessible,但是我不确定我是否完全知道处理暴露关系的最佳方法是什么。假设我们有一个基本的内容创建/所有权网站。用户可以创建博客文章,并拥有一个与该博客文章相关联的类别。
所以我有三个模型:
用户 帖子:属于一个用户和一个类别 类别:属于用户我允许对 category_id 进行批量分配,因此用户可以将其取消,将其更改为他们的类别之一,或者通过批量分配,我想他们可以将其更改为其他人的类别。这就是我有点不确定最好的方法是什么。
我调查的资源(特别是 railscast #178 和该 railscast 提供的 resource)都提到该关联不应该是可批量分配的,这是有道理的。我只是不确定如何让用户更改 post 的 category 内容。
关于如何最好地解决这个问题的任何想法?我看错了吗?
更新:希望能进一步澄清我的担忧。
假设我在 Post,我是否需要类似以下内容:
def create
@post = Post.new(params[:category])
@post.user_id = current_user.id
# CHECK HERE IF REQUESTED CATEGORY_ID IS OWNED BY USER
# continue on as normal here
end
这似乎是很多工作?我需要在更新和创建操作中检查每个控制器。请记住,不仅仅是一个 belongs_to 关系。
【问题讨论】:
【参考方案1】:我想,您的用户可以通过某种编辑表单来更改它。
基于此,Mass Assignment 确实适用于那些试图通过 curl 之类的东西弄乱您的应用程序的邪恶类型。我称他们为卷发小子。
这就是说,如果您使用attr_protected
-(此处放置您不希望他们更改的字段)或孩子最喜欢的attr_accessible
(可以更改的字段)。
您会听到两者的论据,但如果您在模型中使用 attr_protected :user_id
,然后在 CategoryController#create 操作中,您可以执行类似的操作
def create
@category = Category.new(params[:category])
@category.user_id = current_user.id
respond_to do |format|
....#continue on as normal here
end
【讨论】:
谢谢@pjammer。我对上面的例子特别感兴趣。你写的是正确的,但我对从 Post 到 Category 的 belongs_to 更感兴趣。对于 Post 和 Category 上的 current_user,我已经有了类似的东西(虽然我在模型中有)。【参考方案2】:好的,所以搜索了一下,最后想出了一些对我有用的东西。我喜欢尽可能将逻辑排除在控制器之外,因此此解决方案是基于模型的解决方案:
# Post.rb
validates_each :asset_category_id do |record, attr, value|
self.validates_associated_permission(record, attr, value)
end
# This can obviously be put in a base class/utility class of some sort.
def self.validates_associated_permission(record, attr, value)
return if value.blank?
class_string = attr.to_s.gsub(/_id$/, '')
klass = class_string.camelize.constantize
# Check here that the associated record is the users
# I'm leaving this part as pseudo code as everyone's auth code is
# unique.
if klass.find_by_id(value).can_write(current_user)
record.errors.add attr, 'cannot be found.'
end
end
我还发现 rails 3.0 将有一个更好的方法来指定这个而不是超通用 validates_each 所需的 3 行。
http://ryandaigle.com/articles/2009/8/11/what-s-new-in-edge-rails-independent-model-validators
【讨论】:
其他答案非常有帮助,但这实际上解决了我的问题,因此我接受了。以上是关于rails:与belongs_to关系的大规模分配安全问题的主要内容,如果未能解决你的问题,请参考以下文章
在 Rails 中通过其 belongs_to 关系查询记录
Rails 查询具有 has_many 和 belongs_to 关系的模型
如何更新脚手架生成的 MVC + 路由,用于在 Rails 中具有 2 个 belongs_to 关系的嵌套资源
Rails ActiveRecord - 获取与锁定的belongs_to关联