为什么在 Rails 3 中,<%= note.html_safe %>和 <%= h note.html_safe %>给出相同的结果?

发布于 2024-09-30 07:02:04 字数 1639 浏览 4 评论 0原文

感觉就像 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; 后,就可以不要再逃避一次&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 不会自动转义字符串,但是对于。出于某种原因,2.3.10 中已经存在方法 html_safe (出于什么目的?))

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

It feels like html_safe adds an abstraction to the String class that requires understanding of what is going on, for example,

<%= '1 <b>2</b>' %>      # gives 1 <b>2</b> 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 <b>2</b>   wont' escape twice

For line 4, if we are saying, ok, we trust the string -- it is safe, but why can't we escape it? It seems that to escape it by h, the string has to be unsafe.

So on line 1, if the string is not escaped by h, it will be automatically escaped. On line 5, h cannot escape the string twice -- in other words, after < is changed to <, it can't escape it one more time to &lt;.

So what's happening? At first, I thought html_safe is just tagging a flag to the string, saying it is safe. So then, why does h not escape it? It seems that h and html_escape actually co-operate on using the flag:

1) If a string is html_safe, then h will not escape it

2) If a string is not html_safe, then when the string is added to the output buffer, it will be automatically escaped by h.

3) If h already escaped a string, it is marked html_safe, and therefore, escaping it one more time by h won't take any effect. (as on Line 5, and that behavior is the same even in Rails 2.3.10, but on Rails 2.3.5 h can actually escape it twice... so in Rails 2.3.5, h is a simple escape method, but some where along the line to 2.3.10, h became not as simple. But 2.3.10 won't auto escape a string, but for some reason, the method html_safe already exists for 2.3.10 (for what purpose?))

Is that how it works exactly? I think nowadays, sometimes we don't get what we want in the output and we immediately add html_safe to our variable, which can be quite dangerous, because it can introduce XSS attack that way, so understanding how it exactly works can be quite important. The above is only a guess of how it exactly work. Could it be actually a different mechanism and is there any doc that supports it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

前事休说 2024-10-07 07:02:04

如您所见,对字符串调用 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

string 行为确实发生了变化,我认为你对它的运作方式基本上是正确的。一般来说,除非您确定它已经被清理,否则您不应该调用 html_safe。就像任何事情一样,使用时必须小心

As you can see, calling html_safe on a string turns it into an html safe SafeBuffer

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

Any operations on a SafeBuffer that could affect the string safety will be passed through h()

h uses this flag to avoid double escaping

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

The behavior did change and I think you are mostly correct about how it works. In general you should not call html_safe unless you're sure that it is already sanitized. Like anything, you have to be careful while using it

我是男神闪亮亮 2024-10-07 07:02:04

在 Rails 3 中,默认情况下所有输出都使用 h 帮助器,

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

如果您不想转义,可以使用 raw

in rails 3, all output is using the h helper by default

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

if you don't want escaping you can use raw

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文