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

Are there security risks to whitelisting all the column names in a model with strong params?

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

这是我最终想出的:

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

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

像这样设置强参数是否存在安全漏洞?

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

This can be used to pass mass assignment

Is there a security vulnerability with setting strong params up like this?

是的,这违背了白名单的目的。这是允许 some 字段,但不允许其他字段。恶意客户将能够写入您的任何字段。例如,包括 rolesis_admin

如果你没有任何限制字段,你可以完全跳过强参数,只使用 params[:user](或者 params 如果你的属性在顶层,可以从问题)。最终结果将是相同的,但至少您不会对安全抱有任何错误的希望。

I'm in the process of extracting some parts of a project into an engine and I wanted to whitelist user params in such a way that the user doesn't have to configure anything.

地狱之路是用善意铺成的。你实际上在做的只是为你的 gem 的任何用户创建一个 mass assigment vulnerablity

Is there a security vulnerability with setting strong params up like this?

是的。例如,恶意用户可以分配 id 参数或 admin = true。这就是强参数要避免的确切场景。

您还应该明白参数白名单不是模型问题。这种方法被认为存在严重缺陷,因为模型不了解请求并且应该允许的参数可能取决于上下文和授权。

别做那样的人。

作为 gem 作者,您的责任是默认确保安全。约定优于配置意味着提供一组好的默认值——而不是让它变得愚蠢友好。

您可能希望查看 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 which can be changed in an initializer