感觉像html_safe向String类添加了一个抽象,需要了解正在发生的事情,例如,

<%= '1 <b>2</b>' %>      # gives 1 &lt;b&gt;2&lt;/b&gt; in the HTML source code

<%= h '1 <b>2</b>' %>    # exactly the same as above

<%= '1 <b>2</b>'.html_safe %>      #  1 <b>2</b>  in HTML source code

<%= h '1 <b>2</b>'.html_safe %>    #  exactly the same as above

<%= h (h '1 <b>2</b>') %>  #  1 &lt;b&gt;2&lt;/b&gt;   wont' escape twice

对于第4行,如果我们说,好的,我们信任该字符串-这是安全的,但是为什么我们不能对其进行转义?似乎要通过h对其进行转义,该字符串必须是不安全的。

因此,在第1行上,如果h不对字符串进行转义,则将自动对它进行转义。在第5行,h无法两次对字符串进行转义-换句话说,将<更改为&lt;后,就无法再将其转义为&amp;lt;了。

那是怎么回事?起初,我以为html_safe只是在字符串上标记了一个标记,说这是安全的。那么,为什么h无法逃脱呢?看来hhtml_escape实际上在使用该标志方面协作:

1)如果字符串是html_safe,则h将不会对其进行转义

2)如果字符串不是html_safe,则将该字符串添加到输出缓冲区时,它将由h自动转义。

3)如果h已经转义了一个字符串,则将其标记为html_safe,因此,通过h再次转义一次不会产生任何效果。 (与第5行一样,即使在Rails 2.3.10中,行为也相同,但是在Rails 2.3.5上,h实际上可以对其进行两次转义...因此,在Rails 2.3.5中,h是一种简单的转义方法,但是有些沿着2.3.10的行,h变得不那么简单,但是2.3.10不会自动转义字符串,但是由于某种原因,html_safe方法已经存在于2.3.10中(出于什么目的?))

那到底是怎么运作的?我认为,如今,有时我们无法在输出中得到想要的东西,而是立即将html_safe添加到我们的变量中,这很危险,因为它可能会以这种方式引入XSS攻击,因此了解其确切的工作方式非常重要。 。以上只是对它如何工作的猜测。难道实际上是一种不同的机制,是否有任何文档支持该机制?

最佳答案

如您所见,在字符串上调用html_safe会将其转换为html safeSafeBuffer

http://github.com/rails/rails/blob/89978f10afbad3f856e2959a811bed1982715408/activesupport/lib/active_support/core_ext/string/output_safety.rb#L87

对SafeBuffer的任何可能影响字符串安全的操作都将通过h()传递

h使用此标志来避免两次转义

http://github.com/rails/rails/blob/89978f10afbad3f856e2959a811bed1982715408/activesupport/lib/active_support/core_ext/string/output_safety.rb#L18

行为确实发生了变化,我认为您基本上是正确的。通常,除非确定已将其净化,否则不应调用html_safe。像任何东西一样,使用时必须小心

10-07 19:07
查看更多