在具有强params的模型中将所有列名称列入白名单是否存在安全风险?

时间:2017-11-15 11:07:50

标签: ruby-on-rails strong-parameters

我正在将项目的某些部分提取到引擎中,并且我希望将用户参数列入白名单,以便用户不必配置任何内容。

这是我最终提出的:

def user_params
  params.permit(::User.columns.map(&:name), :current_password, :password, :password_confirmation)
end

它到目前为止工作(它允许用户模型中的所有属性,似乎拒绝其他任何东西),但是,我在搜索中找不到另一个实现,以同样的方式执行此操作,我想知道是否那是因为我没有看到的东西。

是否存在安全漏洞,如此设置强大的参数?

3 个答案:

答案 0 :(得分:1)

  

是否存在安全漏洞,如此设置强大的参数?

是的,这违背了白名单的目的。哪个是允许某些字段,而不是其他字段。恶意客户端将能够编写您的任何字段。比方说,包括rolesis_admin

如果您没有任何受限制的字段,则可以完全跳过强参数,只需使用params[:user](或params,如果您的属性位于顶层,可以从问题中看出)。最终结果将是相同的,但至少你不会有任何虚假的安全希望。

答案 1 :(得分:1)

  

我正在将项目的某些部分提取到一个   引擎和我想以这样的方式将用户参数列入白名单   用户无需配置任何内容。

道路上铺满了善意。你实际在做的只是为你的宝石的任何用户创建一个mass assigment vulnerablity

  

是否存在安全漏洞,如设置强大的参数   此?

是。恶意用户可以分配id param或admin = true。多数情况下,强参数的确切情况是要避免的。

您还应该围绕该参数进行包围。白名单不是模型问题。这种方法被认为存在严重缺陷,因为模型不是请求意识,应该允许的参数可以取决于上下文和授权。

不要那个人。

作为宝石作者,您的责任是默认安全。约定优于配置意味着提供一组良好的默认值 - 而不是让它变得白痴友好。

您可能希望查看Devise并提供一组良好的默认参数,并允许用户覆盖它。

class SomeGem::UserController < SomeGem::BaseController

  def create
    @user = User.new(create_params)
    if @user.save
      yield @user if block_given?
      # ...
    else
      # ...
    end
  end

  private 

  def create_params
    params.require(param_key).permit(*base_params)
  end

  def base_params
    :email, :current_password, :password, :password_confirmation
  end

  def param_key
     :user
  end
end

然后可以由gem的用户简单地覆盖它:

class MyUserController < SomeGem::UserController
  private

  def base_params
    super + [:first_name, :last_name]
  end
end

继承的替代方法是使用可在config option中更改的initializer

答案 2 :(得分:0)

您可以使用permit!方法。见Rails API doc

  

这可用于传递质量分配