Rails 5 - 如何在 rails 中从字符串中剥离标签(NOT in/for html)

Rails 5 - How to strip tags from string in rails (NOT in/for html)

提问人:Handsome Jack 提问时间:12/8/2021 最后编辑:Handsome Jack 更新时间:12/8/2021 访问量:496

问:

在保存到数据库之前,我需要从用户输入中剥离标签

我很清楚strip_tags方法,但它也有 html 转义字符串,以及所有其他推荐的方法:

Rails::Html::FullSanitizer.new.sanitize '&'
 => "&" 
Rails::Html::WhiteListSanitizer.new.sanitize('&', tags: [])
 => "&" 
ActionController::Base.helpers.strip_tags "&"
 => "&" 

我要清理的字符串不是要转义的,它通过 API 导出,用于文件等,它不仅通过 HTML 输出(在这种情况下也是如此 - link_to 是双重转义字符串,所以你会在前端获得链接)link_to ActionController::Base.helpers.strip_tags("&")&

作为一个猴子补丁,我已经strip_tags包裹起来以获得或多或少的预期结果,但想找到一些直接的解决方案(我也担心还能strip_tags做什么,而且这个小功能有太多的活动部件 - 更多的东西可能会出错或损坏)CGI.unescapeHTML

真实世界的例子:应该在删除标签后变成JPMorgan Chase & CoJPMorgan Chase & Co

test<script>alert('hacked!');</script>&test剥离标签后应成为test&test

还有字符串:

"test &#x3C;script&#x3E;alert(&#x27;hacked!&#x27;)&#x3C;/script&#x3E;"

应该还是

"test &#x3C;script&#x3E;alert(&#x27;hacked!&#x27;)&#x3C;/script&#x3E;"

剥离 HTML 后

使用我发现或提出的替代解决方案:

> Nokogiri::HTML("test &#x3C;script&#x3E;alert(&#x27;hacked!&#x27;)&#x3C;/script&#x3E;").text
 => "test <script>alert('hacked!')</script>"

> Loofah.fragment("test &#x3C;script&#x3E;alert(&#x27;hacked!&#x27;)&#x3C;/script&#x3E;").text(encode_special_chars: false)
 => "test <script>alert('hacked!')</script>"

所以他们也是不行的

Ruby-on-Rails 条带标签

评论

0赞 Schwern 12/8/2021
你能举一个有问题的字符串的例子和你想要的结果吗?
0赞 Handsome Jack 12/8/2021
我已经更新了真实世界的例子

答:

2赞 Schwern 12/8/2021 #1

您必须解析 HTML 并提取文本元素。使用 Nokogiri 来做到这一点。

Nokogiri::HTML("<div>Strip <i>this</i> & <b>this</b> & <u>this</u>!</div>").text

Nokogiri 已经被 Rails 使用,所以使用它不需要任何费用。


您将获得所有文本,包括标签的内容。<script>

Nokogiri::HTML(%q[test<script>alert('hacked!');</script>&test]).text

# testalert('hacked!');&test

您可以剥离标签。<script>

doc = Nokogiri::HTML(%q[test<script>alert('hacked!');</script>&test])
doc.search('//script').each { |node| node.replace('') }
doc.text

# test&test

但是,剥离标签后,字符串是没有害处的。这可能不值得付出努力。

有关更多信息,请参阅 Nokogiri 教程

评论

0赞 Handsome Jack 12/8/2021
哦,这就是我到底在寻找什么!谢谢!
0赞 Handsome Jack 12/8/2021
啊,不,对不起,它行不通:(在问题底部查看我的更新
0赞 Schwern 12/9/2021
@HandsomeJack 你的最终结果是什么?您是否正在防止 HTML 注入?或者您是从 HTML 中提取文本?似乎两者兼而有之。这些是不同的。如果两者兼而有之,请提取文本,然后转义可能潜伏在文本中的任何 HTML。但是,您应该在使用文本之前(而不是在保存文本时)已经对文本进行了转义;这样你就不会猜测它将如何使用。提取文本,将其存储在数据库中。然后你可以用它来做任何事情。然后在将任何文本放入 HTML 之前对其进行转义,不要以为它已经转义了。