【问题标题】:Strip out script tags before saving to database in rails [duplicate]在保存到rails中的数据库之前去除脚本标签[重复]
【发布时间】:2016-08-19 16:09:49
【问题描述】:

对于我的所有模型应用程序范围:如果用户提交包含<script></script> 标签的 text_field 或 text_area,那么我希望 rails 在将用户的数据输入保存到数据库之前去除这些标签。

我已经看过以下5年左右的帖子:

我还查看了以下文档,但我还没有弄清楚如何将它们应用于这种情况(在持久化到数据库之前删除脚本标签):

示例:

scaffold 获取user 资源:

rails g scaffold user first_name last_name age:integer bio:text

然后用户输入以下内容并提交:

应将此user 记录的每个属性的以下内容保存到数据库中:

  • first_name: Foo
  • 姓氏:Foo
  • 年龄:5
  • 简介:巴兹

谢谢!

【问题讨论】:

  • @Ven 这只是一个安全网。如果程序员没有在视图中正确转义,可能是通过 AJAX 请求。有关程序员在视图中未正确转义并且脚本标签保留在数据库中的示例,请参阅此问题:stackoverflow.com/questions/39039731/… 如果在保存之前删除了所有脚本标签,我们不再需要担心。
  • Rails 为您逃脱。程序员不会逃避自己。这是 2016 年。

标签: ruby-on-rails ruby


【解决方案1】:

如果您只想在渲染 HTML 时进行清理,RoR 已经提供了一个帮助程序 (http://api.rubyonrails.org/classes/ActionView/Helpers/SanitizeHelper.html),可以让您自动清理这些标签。

如果您希望他们在将这些生物字段存储到您的数据库之前对其进行清理,那么有一个 gem (sanitize) 可以轻松完成。该 gem 可让您配置要保留的标签(如果有)并将其余标签列入黑名单。

-- 使用 strong_params,您通常在控制器中有一个辅助方法,以便 requirepermit 属性。被允许后,你可以遍历这些参数并检查其中的一些(或全部)

# using the sanitize gem
def sanitize input_field
  Sanitize.fragment(input_field, Sanitize::Config::RELAXED)
end

def sanitize_product_input 
  # product_params = strong_params filter
  [:first_name, :last_name, :bio].each do |field|
    product_params[field] = sanitize(product_params[field])
  end
  product_params
end

或者您可以更通用地执行此操作,并在您的 application_controller 中创建一种新方法来清理输入

# using the sanitize gem
def sanitize input_field
  Sanitize.fragment(input_field, Sanitize::Config::RELAXED)
end

def sanitize_input input_params, fields
  fields.each do |field|
    input_params[field] = sanitize(input_params[field])
  end
end

并在您定义 strong_params 过滤器的方法中使用它

def product_params 
  fields = [:first_name, :last_name, :bio]
  input_params = params.require(:product).require(fields)
  sanitize_input(input_params, fields)
  input_params
end

【讨论】:

  • 您能否提供应用sanitize gem 的代码来解决问题中提供的示例?我想清理此模型的 first_namelast_namebio 属性。但更全球化:我还想清理所有表单的所有文本字段,以便用户永远无法提交<script> 标签。我将如何使用带有 strong_params 的 sanitize gem?
  • 使用 strong_params 你通常在你的控制器中有一个辅助方法来 requirepermit 属性。获得许可后,您可以遍历这些参数并检查其中一些(或全部)` def sanitize_product_input # product_params = strong_params filter [:first_name, :last_name, :bio].each do |field| product_params[field] = sanitize(product_params[field]) end product_params end `
  • 您的方法sanitize(product_params[field]) 在控制器中不起作用。 sanitize 方法是一个视图助手,不能在控制器中使用。
  • 这是视图的 Rails 助手的名称。但是,如果您在 application_controller 中创建一个新方法(sanitize),那么它将起作用(在示例中我使用了 sanitize gem)
  • 感谢您的帮助。使用 Sanitize gem,您不必这样做:Sanitize.fragment(some_string),甚至 Sanitize.fragment(some_string, Sanitize::Config::RELAXED)
【解决方案2】:

一种可能的解决方案是使用sanitize_model_attributes gem

基本上:这会覆盖您在 sanitize_attributes 方法中指定的所有模型属性的设置器,以便它可以清理每个属性的 value

实施

#app/models/user.rb
class User < ApplicationRecord
  include SanitizeModelAttributes
  sanitize_attributes :first_name, :last_name, :bio
end

就像这样:所有 html标签(不仅仅是脚本标签)在保存到数据库之前被删除以获取first_namelast_namebio的属性.

【讨论】:

    猜你喜欢
    • 2012-09-20
    • 1970-01-01
    • 2018-03-12
    • 1970-01-01
    • 2012-10-09
    • 2015-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多