【问题标题】:Rails Gem sanitize - How to whitelist &Rails Gem sanitize - 如何加入白名单和
【发布时间】:2011-12-24 17:47:30
【问题描述】:

现在我们正在使用 sanitize gem:https://github.com/rgrove/sanitize

问题是如果您输入“hello & world”,sanitize 会将其保存在数据库中:

hello & world 

如何将 & 列入白名单。我们希望清理以删除所有可能的恶意 html 和 JS/script 标签。但我们可以允许 & 符号。

想法?谢谢

【问题讨论】:

  • 可能是 Sanitize.clean(html, Sanitize::Config::RELAXED) # => '&'
  • 谢谢,但 RELAXED 几乎允许一切。我想加入白名单,但不知道如何
  • @bilash.saha 轻松的配置仍将 html-escape 实体,您发布的内容仍将输出“Hello & world”
  • 使用Loofah - 它内置并且完美:)

标签: ruby-on-rails ruby-on-rails-3 gem sanitize


【解决方案1】:

Sanitize 将始终将输出内容转换为有效 html/xhtml 的 html 实体。

我能确定的最好方法是过滤输出

Sanitize.fragment("hello & world").gsub('&','&') #=> "Hello & world"

【讨论】:

  • 这将解决 & 字符,但不会扩展到 html 引擎使用将转换为实体的所有各种字符。试图跟踪所有这些也会令人头疼。 @agustin 下面的答案是一个更好的解决方案 IMO
  • @ShyamHabarakada Rails 内置的sanitize()strip_tags 的问题是它们不能纠正格式错误的标记,因此不匹配的< 字符会破坏页面布局. strip_tags('Strip <ithese tags') #=> "Strip <ithese tags",但这超出了问题所要求的范围:一种消毒方法,但仍允许使用原始 & 符号。
  • 没错,关于格式错误的标记。我们清理主要是为了防止 HTML 进入不应包含 HTML 的参数。通过内置的 strip_tags 剥离标签对我们来说效果很好。听起来这也是这个问题的场景。我同意,如果您想要全面清理,则需要具有适当 DOM 引擎的更好解决方案。但是对于参数清理,IMO,这似乎有点矫枉过正。
【解决方案2】:

【讨论】:

【解决方案3】:

UnixMonkey 的答案是我们最终所做的。

def remove_markup(html_str)
    marked_up = Sanitize.clean html_str

    ESCAPE_SEQUENCES.each do |esc_seq, ascii_seq|
      marked_up = marked_up.gsub('&' + esc_seq + ';', ascii_seq.chr)
    end
    marked_up
  end

其中 ESCAPE_SEQUENCES 是我们不想转义的字符数组。

【讨论】:

    【解决方案4】:

    从 Rails 4.2 开始,#strip_tags 不会取消编码 HTML 特殊字符

    strip_tags("fun & co")
      => "fun & co"
    

    否则你会得到以下结果:

    strip_tags("<script>")
      => "<script>"
    

    如果你只想要 & 符号,我建议像 @Unixmonkey 建议的那样过滤输出,并将其保留为 &amp; only

    strip_tags("<bold>Hello & World</bold>").gsub(/&amp;/, "&")
      => "Hello & World"
    

    【讨论】:

      【解决方案5】:

      其他答案都不适合我。我为我的用例找到的最佳方法是使用内置的Loofah gem:

      good = '&'
      bad = "<script>alert('I am evil');</script>"
      greater_than = '>' # << my use case
      
      Loofah.fragment(good).text(encode_special_chars: false)
      # => "&"
      Loofah.fragment(greater_than).text(encode_special_chars: false)
      # => ">"
      
      Loofah.fragment(bad).text(encode_special_chars: false)
      # => "alert('I am evil');"
      
      # And just for clarity, without the option passed in:
      Loofah.fragment(good).text
      # => "&amp;"
      

      但它并非完美无瑕,所以要非常小心:

      really_bad = "&lt;script&gt;alert('I am evil');&lt;/script&gt;"
      Loofah.fragment(really_bad).text(encode_special_chars: false)
      # => "<script>alert('I am evil');</script>"
      

      关于指定方法here的更多信息。

      绝对是我需要做的最有效的方法!

      【讨论】:

      • 当你说“内置”是什么意思?它内置在 Rails 中吗?它看起来像一个像 sanitize 一样的宝石,这不是我认为内置的。
      • 它包含在 Rails @Dan 中。 gem dependency loofah --reverse-dependencies 给你(除其他外):Used by rails-html-sanitizer-1.3.0 (loofah (~&gt; 2.3))。该 Gem 本身内置在 Rails 中,请参阅 here:“在 Rails 4.2 及更高版本中,此 gem 将负责清理 Rails 应用程序中的 HTML 片段”。
      猜你喜欢
      • 1970-01-01
      • 2011-10-02
      • 1970-01-01
      • 2011-01-21
      • 1970-01-01
      • 1970-01-01
      • 2021-02-21
      • 1970-01-01
      • 2020-03-30
      相关资源
      最近更新 更多