为什么切割params散列会对批量分配造成安全问题?

时间:2011-09-20 10:07:30

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

通过批量分配防止安全风险的官方方法是使用attr_accessible。但是,一些程序员认为这不是模型的工作(或者至少不是模型的 )。在控制器中执行此操作的最简单方法是切片 params 哈希:

@user = User.update_attributes(params[:user].slice(:name))

然而,文件说明:

  

请注意,使用Hash#except或Hash#slice代替attr_accessible   消毒属性不会提供足够的保护。

为什么? 为什么 params 的白名单切片无法提供足够的保护?

UPDATE: Rails 4.0 will ship strong-parameters,一个精致的参数切片,所以我猜整个切片的事情毕竟不是那么糟糕。

5 个答案:

答案 0 :(得分:6)

切片和控制器除外的问题可能与模型中的accept_nested_attributes_for结合使用。如果使用嵌套属性,则需要在所有位置切片参数,在控制器中更新它们,这并不总是最简单的任务,尤其是对于深度嵌套的方案。使用attr_accesible时,您没有遇到此问题。

答案 1 :(得分:4)

从Rails 4开始,切片参数将成为处理质量分配安全性的首选方法。 Rails核心团队已经开发了一个插件来处理这个问题,他们正在努力集成对嵌套属性和签名表单的支持。绝对值得一看:http://weblog.rubyonrails.org/2012/3/21/strong-parameters/

答案 2 :(得分:4)

来自DHH的有趣的要点是控制器切换与单独白名单:

https://gist.github.com/1975644

class PostsController < ActionController::Base
  def create
    Post.create(post_params)
  end

  def update
    Post.find(params[:id]).update_attributes!(post_params)
  end

  private
    def post_params
      params[:post].slice(:title, :content)
    end
end

评论强化了在控制器内管理这一点的必要性:

https://gist.github.com/1975644#gistcomment-88369

我个人同时应用两者 - attr_accessible with slice以确保没有意外通过。永远不要单靠黑名单!

答案 3 :(得分:2)

只需从params哈希中删除:name就可以防止为该操作设置该属性。它仅适用于您记得保护的操作。

但是,这种做法并不能保护您免受使用为关联自动添加的所有方法的滥用。

class User < ActiveRecord::Base
  has_many :comments
end
即使您从params中删除comments_ids属性,

也会让设置comments属性的人容易受到攻击。

由于为关联添加了很多方法,并且由于它们将来可能会发生变化,因此最佳做法是使用attr_accessible保护模型上的属性。这将最有效地阻止这种攻击。

答案 4 :(得分:0)

@tokland你的最后评论在某种程度上是不正确的。除非您的网站将浏览器作为数据进入和退出的唯一入口点。

如果您的webapp具有API或与控制器级别的其他API保护通信,则会在其后面留下漏洞,并且不会清理或检查来自其他来源的所有数据。我建议保持原样,在application.rb中启用批量分配保护,并推动ActiveSupport FormHelpers像Django / Python样式一样工作。