Rails 4 参数;如何将参数列入一组值的白名单

Nic*_*ick 5 ruby security validation ruby-on-rails controllers

我已经阅读了一些帖子,例如在 Rails 4 中使用强参数的值白名单,但这并不是我所需要的。

我有一个控制器,它需要一个 ID 并加载一个模型。它还可选地采用查询字符串 param ( style) ,它可以是 3 个值之一,small,medium或large。这被传递给模型上的一个方法,该方法使用它来获取附加的图像(使用回形针)。我注意到如果我传递了一个无效的参数(例如style=wibble),那么我会收到一个 400 错误并通知内部文件路径不存在。Brakeman 还指出这是一个安全问题......

def show
  style = params[:style] || :medium

  thing = Model.find(params[:id])

  path = "#{Rails.root}/public#{thing.image_url(style)}"
  content_type = thing.image.content_type || 'image/png'
  send_file path, type: content_type, disposition: 'inline'
end
Run Code Online (Sandbox Code Playgroud)

我们在其他地方使用ActionController 参数效果很好;但我看不到如何将参数选项“列入白名单”?我所看到的任何地方都说要使用模型验证器,但这是假设我正在提交一个参数来更新模型,而我不是。

我知道我可以这样做:

return head :not_found unless %w(small medium large).include? style
Run Code Online (Sandbox Code Playgroud)

这是最好的方法吗?

m. *_*org 5

我写了一个 gem,它ActionController::Parameters正是为了这个目的而扩展的:将参数值列入白名单。它简单且轻便。你可以像这样使用它:

def model_params
  params.require(:model).permit(:style, :other_attribute).allow(style: %w[small medium large])
end
Run Code Online (Sandbox Code Playgroud)

希望你觉得它有用

https://github.com/msimonborg/allowable

  • @MrYoshiji 谢谢,这是非常好的反馈。我在开发它时考虑到了“ActionController::Parameters”,因此它的实现可能不是“Hash”的最佳实现。我认为在单独的模块中单独实现“Hash”将解决这些有效问题 (2认同)

MrY*_*iji 4

首先,您需要定义一个常量,将所有有效值列入白名单style(我认为这size_type是一个更明确的名称)。(注意符号/字符串比较)。

params[:style]然后,如果未包含在白名单值中,则返回 404 ,或者回退到'medium':

style = Model::AVAILABLE_SIZE_TYPES.include?(params[:style]) ? params[:style] || Model::AVAILABLE_SIZE_TYPES.first
Run Code Online (Sandbox Code Playgroud)

就我个人而言,我不喜欢用户输入的后备。他们做错了什么(操纵 URL、更改表单中的值等),他们应该得到一个错误页面。

我暗示该常量是在模型中定义的,但它不应该在那里,因为它与业务逻辑无关,但与模型的显示有关。如果您有 ModelDecorator,请在那里定义它。

  • 除此之外,[看起来像](https://github.com/thoughtbot/paperclip#post-processing)使用回形针,模型可能设置为`has_attached_file :avatar, styles: {thumb: ["32x32#" , :png] }` 所以我可能建议也使用常量 `AVAILABLE_SIZE_TYPES = {thumb: ["32x32#", :png] }` `has_attached_file :avatar, styles: AVAILABLE_SIZE_TYPES` 然后是 `Model:: AVAILABLE_SIZE_TYPES.has_key?(params[:style])` (再次观察字符串/符号)...单一事实来源...如果您稍后添加 `:tiny`,它已经更新了。 (2认同)