9

感觉就像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逃避呢?似乎h并且html_escape实际上合作使用该标志:

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

2)如果一个字符串不是html_safe,那么当这个字符串被添加到输出缓冲区时,它会被自动转义h

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

它是这样工作的吗?我认为现在,有时我们在输出中没有得到我们想要的东西,我们立即添加html_safe到我们的变量中,这可能非常危险,因为它会以这种方式引入 XSS 攻击,因此了解它的确切工作原理可能非常重要。以上只是对其具体工作方式的猜测。它实际上可能是一种不同的机制吗?是否有任何支持它的文档?

4

2 回答 2

6

如您所见,对字符串调用 html_safe 会将其转换为 html 安全 SafeBuffer

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。像任何东西一样,你在使用它时必须小心

于 2010-11-01T15:52:44.987 回答
0

在 rails 3 中,所有输出h默认使用 helper

http://origami.co.uk/blog/2010/02/rails-3-html-escaping

如果你不想逃跑,你可以使用raw

于 2012-12-12T12:55:27.367 回答