【问题标题】:rails: mass-assignment security concern with belongs_to relationshipsrails:与belongs_to关系的大规模分配安全问题
【发布时间】:2011-01-10 16:09:12
【问题描述】:

我一直在阅读有关 Rails 安全问题的信息,其中让我最担心的是批量分配。我的应用程序正在使用 attr_accessible,但是我不确定我是否完全知道处理暴露关系的最佳方法是什么。假设我们有一个基本的内容创建/所有权网站。用户可以创建博客文章,并拥有一个与该博客文章相关联的类别。

所以我有三个模型:

  • 用户
  • 帖子:属于一个用户和一个类别
  • 类别:属于用户

我允许对 category_id 进行批量分配,因此用户可以将其取消,将其更改为他们的类别之一,或者通过批量分配,我想他们可以将其更改为其他人的类别。这就是我有点不确定最好的方法是什么。

我调查的资源(特别是 railscast #178 和该 railscast 提供的 resource)都提到该关联不应该是可批量分配的,这是有道理的。我只是不确定如何让用户更改 postcategory 内容。

关于如何最好地解决这个问题的任何想法?我看错了吗?

更新:希望能进一步澄清我的担忧。

假设我在 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 关系。

【问题讨论】:

    标签: ruby-on-rails security mass-assignment


    【解决方案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

    【讨论】:

    • 其他答案非常有帮助,但这实际上解决了我的问题,因此我接受了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多