web-dev-qa-db-ja.com

Ruby on railsでhtmlをエスケープしないでください

Rails 3は、htmlを含むすべてをエスケープするようです。 raw()を使用しようとしましたが、それでもhtmlをエスケープします。回避策はありますか?これは私が使用している私のヘルパーです(/helpers/application_helper.rb):

module ApplicationHelper
  def good_time(status = true)
    res = ""
    if status == true
      res << "Status is true, with a long message attached..."
    else
      res << "Status is false, with another long message"
    end
  end
end

私はこのコードを使用して私のビューでヘルパーを呼び出しています:

<%= raw(good_time(true)) %>
50
alexyorke

次のように.html_safeを使用できます。

def good_time(status = true)
  if status
    "Status is true, with a long message attached...".html_safe
  else
    "Status is false, with another long message".html_safe
  end
end

<%= good_time(true) %>
88
Mischa

特に動的な文字列を導入すると、これと同じことに遭遇し、_html_safe_を使用するよりも安全なソリューションを発見しました。

まず、更新されたコード:

_def good_time(long_message1, long_message2, status = true)
  html = "".html_safe
  html << "Status is #{status}, "
  if status
    html << long_message1
  else
    html << long_message2
  end
  html
end

<%= good_time(true) %>
_

これは、安全でない場合は_long_message_コンテンツをエスケープしますが、安全な場合はエスケープしません。

これにより、_"long message for success & such."_が正しく表示されますが、"malicious message <script>alert('foo')</script>"もエスケープされます。

説明はこれに要約します-_'foo'.html_safe_はActiveSupport :: SafeBufferを返します。これは、1つを除くすべての点で文字列のように動作します。 SafeBufferに追加される前にHTMLエスケープされます。別のSafeBufferをSafeBufferに追加すると、エスケープは発生しません。 Railsは、SafeBuffersを使用してすべてのビューを内部でレンダリングしているため、上記の更新されたメソッドは、実行するように制御したSafeBufferをRails 「常に」ではなく「必要に応じて」_long_message_でエスケープします。

さて、この答えの功績は完全にヘニング・コッホにあり、詳細については html_safeについて知っていることはすべて間違っています で説明しています。上記の要約では、説明の本質を説明するだけです。このリンクが死ぬというイベント。

3