如何对字符串进行HTML编码/转义?有内置的吗?


98

我有一个不可信任的字符串,我想将其显示为HTML页面中的文本。我需要将字符“ <”和“ &” 转义为HTML实体。大惊小怪越好。

我使用的是UTF8,不需要其他带有重音符号的实体。

Ruby或Rails中是否有内置函数,还是应该自己滚动?


2
根据OWASP的说法,为了对 HTML元素内容进行适当的XSS保护,应转义以下六个字符:&<>"'/
sffc 2014年

Answers:


94

hhelper方法:

<%=h "<p> will be preserved" %>

嗯,它也转义了>,这是不必要的,但是会的。
kch

您可以使用括号来打印带有h的内容和带有不带h的内容。<%= h(“ <p”)+“>”%>
Trevor Bramble 2009年

现在那太傻了。我不在乎它是否能逃脱。我只是注意到html规范不是必需的。
kch

12
由于XML规范相当讨厌地坚持']]>'不得包含在文本中,因此XHTML 有时会需要它(请参见'CharData'产生)。这使得通常更容易(且无害)始终逃避它。
bobince

19
对于那些有兴趣h是一个别名html_escape
lightswitch05

141

检出Ruby CGI类。有编码和解码HTML以及URL的方法。

CGI::escapeHTML('Usage: foo "bar" <baz>')
# => "Usage: foo &quot;bar&quot; &lt;baz&gt;"

12
谢谢,这很好,因为可以从控制器完成。当然,我不会那样做。
Dan Rosenstark 2011年

2
这在功能/集成测试中很有用,用于检查插入模板的内容的正确性(假定内容应转义为HTML)。
Alex D

如果内容在客户网站(而不是您自己的网站)上显示在客户网站上,则在插入数据库之前转义html有什么问题?还有其他解决方法吗?
n00b

对-在进入数据库之前转义是很棒的。您只想确保在添加之前没有任何未曾逃脱的旧黑客……
Kevin

5
我更喜欢它的同义词:CGI.escape_html
Trantor Liu

77

在Ruby on Rails 3中,默认情况下将转义HTML。

对于非转义字符串,请使用:

<%= raw "<p>hello world!</p>" %>

25

ERB :: Util.html_escape可以在任何地方使用。不使用requireRails 就可以使用。


这实际上是CGI.escapeHTML在下面使用
akostadinov

@akostadinov-结果不同。例如,ERB :: Util.html_escape会将撇号转换为&#x27;。而CGI :: escapeHTML则不会-Louis
Sayers

@LouisSayers,我看不到怎么发生:```[43] pry(main)> show-source ERB :: Util.html_escape来自:/usr/share/ruby/erb.rb @第945行:所有者:#<Class:ERB :: Util>可见性:公共行数:3 def html_escape CGI.escapeHTML(s.to_s)结尾```
akostadinov

@akostadinov-嗯...再次运行,是的,他们产生了相同的输出。我发誓在工作中运行时会产生不同的结果(也许erb / cgi版本的行为不同?)。我必须看看为什么明天我在工作中得到不同的结果。
路易·赛尔斯

17

除了克里斯托弗·布拉德福德(Christopher Bradford)的答案之外,CGI它还可以在任何地方使用HTML转义,因为现在大多数人不使用HTML,所以您也可以使用Rack

require 'rack/utils'
Rack::Utils.escape_html('Usage: foo "bar" <baz>')

在模型实例方法中,是否有更好的方法以类似的方式转义字符串?
编码有效,

15

您可以使用h()html_escape(),但是大多数人都h()按惯例使用。 h()html_escape()rails中的缩写。

在您的控制器中:

@stuff = "<b>Hello World!</b>"

您认为:

<%=h @stuff %>

如果您查看HTML源代码:您将看到输出而没有实际加粗数据。即它被编码为&lt;b&gt;Hello World!&lt;/b&gt;

它将显示为 <b>Hello World!</b>


9

不同方法的比较:

> CGI::escapeHTML("quote ' double quotes \"")
=> "quote &#39; double quotes &quot;"

> Rack::Utils.escape_html("quote ' double quotes \"")
=> "quote &#x27; double quotes &quot;"

> ERB::Util.html_escape("quote ' double quotes \"")
=> "quote &#39; double quotes &quot;"

我写了自己的代码以与Rails ActiveMailer转义兼容:

def escape_html(str)
  CGI.escapeHTML(str).gsub("&#39;", "'")
end

0

h() 对于转义引号也很有用。

例如,我有一个使用文本字段生成链接的视图result[r].thtitle。文本可以包含单引号。如果我没有result[r].thtitle在Confirm方法中转义,则Javascript会中断:

&lt;%= link_to_remote "#{result[r].thtitle}", :url=>{ :controller=>:resource,
:action         =>:delete_resourced,
:id     => result[r].id,
:th     => thread,                                                                                                      
:html       =>{:title=> "<= Remove"},                                                       
:confirm    => h("#{result[r].thtitle} will be removed"),                                                   
:method     => :delete %>

&lt;a href="#" onclick="if (confirm('docs: add column &amp;apos;dummy&amp;apos; will be removed')) { new Ajax.Request('/resource/delete_resourced/837?owner=386&amp;th=511', {asynchronous:true, evalScripts:true, method:'delete', parameters:'authenticity_token=' + encodeURIComponent('ou812')}); }; return false;" title="&lt;= Remove">docs: add column 'dummy'</a>

注意::htmlRails神奇地将标题声明转义了。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.