通过批量分配防止安全风险的官方方法是使用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,一个精致的参数切片,所以我猜整个切片的事情毕竟不是那么糟糕。
答案 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样式一样工作。