2010-11-01 37 views
9

感覺就像html_safe增加了一個抽象的String類,需要到底是怎麼回事,例如理解,爲什麼在Rails 3中,<%= note.html_safe%>和<%= h note.html_safe%>給出了相同的結果?

<%= '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攻擊,所以理解它的正確工作方式可能非常重要。以上只是猜測它是如何工作的。它可能實際上是一個不同的機制,有沒有支持它的文檔?

回答

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。任何事情一樣,你必須在使用它

+1

有趣...它使用一個新的類SafeBuffer作爲「標誌」...所以'「foobar」.html_safe'實際上會創建並返回一個帶有原始字符串內容的SafeBuffer新實例... – 2010-11-01 16:32:38

相關問題