Rails安全性:完全避免批量分配

时间:2011-03-24 19:26:13

标签: ruby-on-rails security activerecord

我的生产代码中往往不需要mass-assignment功能。 (在我的测试代码中,我经常使用它,但在那些情况下,我想要设置任意列。)

因此,如果在我的生产代码中,我只是避免使用这些形式:

Article.new(params[:article])  # or create
article.attributes = params[:article]
article.update_attributes(params[:article])

而是始终手动枚举所有属性,如下所示:

Article.new(:title => params[:article][:title], :body => params[:article][:body], ...)

我是否从质量分配安全问题中解决了问题(即使不使用attr_accessible / attr_protected)?

编辑:我不仅仅禁用批量分配的原因是,我希望能够编写Article.create!(:blog_id => @blog.id, ...),其中blog_id是一个“未保存”属性。

3 个答案:

答案 0 :(得分:10)

是的,使用第二种方法,您可以安全地从用户分配其他属性。

这是一种干燥的写作方式,但是:

Article.new(params[:article].slice(:title, :body))

-OR -

def article_params
  params[:article].slice(:title, :body)
end

Article.new(article_params)  # or create
article.attributes = article_params
article.update_attributes(article_params)

答案 1 :(得分:2)

config/environments/production.rb

的末尾添加此内容
ActiveRecord::Base.send(:attr_accessible, nil)

答案 2 :(得分:0)

我无法让John Douthat的方法为多个参数工作,所以我想出了以下替代方案(取自我的CommentsController):

def set_params
  @comment.parent_id = params[:blog_comment][:parent_id] 
  @comment.ip_address = request.remote_ip
  @comment.commentator = current_user.username || "anonymous"
  @comment.name = params[:blog_comment][:name]
  @comment.email = params[:blog_comment][:email]
  @comment.url = params[:blog_comment][:url]
end

def create
  @comment = @post.comments.build(params[:blog_comment])
  set_params

  if @comment.save
  ...
end

def update
  @comment = Blog::Comment.find(params[:id])
  set_params

  if @comment.update_attributes(params[:blog_comment])
  ...
end