Почему в Rails 3 <% = note.html_safe%> и <% = h note.html_safe%> дают одинаковый результат?

Похоже на 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.5 h может на самом деле избежать этого дважды... так в Rails 2.3.5, h это простой метод побега, но кое-где по линии к 2.3.10, h стало не так просто. Но 2.3.10 не будет автоматически экранировать строку, но по какой-то причине метод html_safe уже существует для 2.3.10 (для каких целей?))

Это именно так и работает? Я думаю, что в настоящее время, иногда мы не получаем то, что мы хотим в выводе, и мы сразу добавляем html_safe к нашей переменной, которая может быть довольно опасной, потому что она может ввести XSS-атаку таким образом, поэтому понимание того, как именно она работает, может быть весьма важным. Выше это только предположение о том, как именно это работает. Может ли это быть на самом деле другой механизм, и есть ли какой-нибудь документ, который его поддерживает?

2 ответа

Как видите, вызов 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, если вы не уверены, что он уже очищен. Как и все, вы должны быть осторожны при использовании

В рельсах 3 весь вывод использует h помощник по умолчанию

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

если вы не хотите убежать, вы можете использовать raw

Другие вопросы по тегам