Ruby on Rails:使用清理助手在代码块内允许小于号“<”

Posted

技术标签:

【中文标题】Ruby on Rails:使用清理助手在代码块内允许小于号“<”【英文标题】:Ruby on Rails: Allow less than sign '<' inside code block with sanitize helper 【发布时间】:2016-07-22 03:23:13 【问题描述】:

我试图在 Rails 中转义用户生成的内容。我使用带有 sanitizeraw 助手的 raw 来过滤如下内容:

raw(sanitize(code, :tags =>   ['<', 'h2','h3','p','br','ul','ol','li','code','pre','a'] ))

内容中允许提及的标签列表。

问题是当我尝试使用这样的 sql 查询对其进行测试时:

mysql -u sat -p -h localhost database <  data.sql

precode 块中,它会删除小于 (

请帮我想办法做到这一点。

【问题讨论】:

我无法在控制台中重现您的问题。也许您应该显示您传递给sanitize 的确切内容。此外,“ 这一行:“
mysql -u sat -p -h localhost database ”将只导致:“mysql -u sat -p -h localhost数据库”,并且结束的 pre 标记也被删除。这会导致奇怪的标记。
我认为这与数据在数据库中的存储方式有关。您能建议存储和呈现源代码的最佳方式吗? 嗯,渲染是您一直在问的问题,但就存储而言,我不明白您为什么要使用比足够大的字符串类型更复杂的东西。如果您的数据库破坏了您的内容,您应该能够通过前后比较来检测到这一点。 不,不是。这只是渲染问题。我正在使用 raw 和 sanitize 助手: raw(sanitize(code, :tags => ['h2','h3','p','br','blockquote', 'ul','ol','li ','强','代码','pre','a']))。它工作正常,除了遇到' 【参考方案1】:

Rails 3 为每个 String 实例添加了 html_safe 属性。除非 html_safe 设置为 true(简化),否则打印或插入数据库的每个字符串都将被转义。 raw 所做的实际上是将html_safe 设置为true。所以你应该只传递一个已经安全/转义的字符串。

可能的解决方案如下所示:

strip_tags(code).html_safe

您可能需要根据您的用例添加额外的检查/字符串替换。

根据您的评论,您可能需要更复杂的版本。您可以尝试替换您希望允许的所有字符,清理字符串,然后反转替换,以避免清理方法清理的内容超出您的实际需要。试试这样的:

code = "mysql -u sat -p -h localhost database < data.sql"

ALLOWED_SIGNS = 
  :lower_than => "<".html_safe


s = code.dup
ALLOWED_SIGNS.each  |k, v| s.sub!(v, "%#k") 
sanitize(s) % ALLOWED_SIGNS

【讨论】:

问题是我必须清理用户输入,但还允许问题中所述的某些 html 标签。问题是 sanitize 也删除了小于号 ' 我已经更新了我的答案并添加了一些仍然使用sanitize 方法的示例代码。因此,您可以以与您的问题相同的方式添加您允许的 tags【参考方案2】:

这可能会有所帮助,sanitizer 可以选择提供在清理期间需要忽略的标签和属性的白名单

ActionView::Base.full_sanitizer.sanitize(html_string) #Basic Syntax

标签和属性的白名单可以指定如下

ActionView::Base.full_sanitizer.sanitize(html_string, :tags => %w(img br p), :attributes => %w(src style))

上面的语句允许标签:img、br 和 p 以及属性:src 和 style。

【讨论】:

您将如何允许问题中的 mysql 查询中提到的小于“ 在我的一个应用程序中,这就是我允许 img、br、p 元素和 src 、样式属性的方式。由于 ' 如果您注意我的问题描述,这正是我允许标签的方式。如果我可以“尝试一些解决方法”,我就不会在这里问这个问题了。 @IslamWazery 完全正确【参考方案3】:

我不相信在 Rails 中使用默认的清理方法是不可能的。

尝试使用 Sanitize gem (https://github.com/rgrove/sanitize)

require 'sanitize'

allowed_elements = ['h2','h3','p','br','ul','ol','li','code','pre','a']
code             = "<pre>mysql -u sat -p -h localhost database < data.sql</pre>"

Sanitize.fragment(code, elements: allowed_elements)
# => <pre>mysql -u sat -p -h localhost database &lt; data.sql</pre>

要使用它来将清理过的内容保存到数据库中,请向您的模型添加一个 before_save 过滤器,该过滤器对用户生成的内容运行清理并存储结果,例如

class MyModel < ActiveRecord::Base 
  ALLOWED_ELEMENTS = ['h2','h3','p','br','ul','ol','li','code','pre','a']

  before_save :sanitize_code

  private

  def sanitize_code
    self.code = Sanitize.fragment(code, elements: ALLOWED_ELEMENTS)
  end
end

当您输出内容时,您只需要使用原始视图帮助器,例如

<%= raw @instance.code %>

【讨论】:

【参考方案4】:

似乎整个问题都在于数据在数据库中的存储方式。以前,小于号“&lt;,这似乎解决了问题。

我在使用tinymce-rails WYSIWYG 编辑器时意外地理解了这一点,该编辑器自动转义了“

@kieran-johnson 的回答可能也是如此,但 tinymce-rails 无需安装额外的 gem 即可解决。

感谢所有抽出时间提供帮助的人。

【讨论】:

【参考方案5】:

nokogirigem 解决问题:

宝石'nokogiri'

Nokogiri::HTML::DocumentFragment.parse('<b>hi</b> x > 5').text
 => "hi x > 5" 

【讨论】:

【参考方案6】:

在通过 sanitize 方法运行之前,请考虑将“&#60;。它应该被转换成&amp;lt;,然后呈现为“

【讨论】:

以上是关于Ruby on Rails:使用清理助手在代码块内允许小于号“<”的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ruby​​ on rails 中访问 rails 助手和嵌入资产 javascript 文件中的 ruby​​?

在 ruby​​ on rails 中公开函数

Ruby on Rails 使用视图助手中的变量在视图中动态生成字段名称

Ruby on Rails:不使用 find 时如何为 SQL 清理字符串?

Ruby on Rails 中一个共享视图的两个控制器

Ruby on rails 辅助方法实例变量