Rails 安全:完全避免大规模分配

发布于 2024-10-25 21:53:42 字数 726 浏览 1 评论 0原文

我的生产代码中往往不需要 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 是“未保存”属性。

I tend to not need the mass-assignment feature in my production code. (In my test code, I use it a lot, but in those cases I do want to set arbitrary columns.)

So if, in my production code, I simply avoid these forms:

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

and instead always manually enumerate all the attributes, like so:

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

am I save from mass assignment security issues (even without using attr_accessible/attr_protected)?

Edit: The reason I'm not just disabling mass assignment is, I'd like to be able to write Article.create!(:blog_id => @blog.id, ...), where blog_id is an "unsave" attribute.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

空城缀染半城烟沙 2024-11-01 21:53:42

是的,使用第二种方法,您可以避免用户分配给其他属性。

不过,这是一种比较干燥的写法:

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

-或者-

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

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

Yes, using the 2nd method, you're safe from users assigning to other attributes.

This is a DRYer way to write it, though:

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)
獨角戲 2024-11-01 21:53:42

将其添加到 config/environments/Production.rb 的末尾:

ActiveRecord::Base.send(:attr_accessible, nil)

Add this at the end of config/environments/production.rb :

ActiveRecord::Base.send(:attr_accessible, nil)
烟沫凡尘 2024-11-01 21:53:42

我无法让 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

I could not get John Douthat's method working for multiple parameters, so I came up with the following alternative (taken from my 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文