9

何が起こっているのかを理解する必要がある String クラスに抽象化を追加するように感じ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は、文字列を 2 回エスケープすることはできません。つまり、<が に変更された後&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では実際に2回エスケープできます...したがって、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デフォルトでヘルパーを使用しています

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

エスケープしたくない場合は、使用できますraw

于 2012-12-12T12:55:27.367 に答える