Почему в Rails 3 <% = note.html_safe%> и <% = h note.html_safe%> дают одинаковый результат? - PullRequest
9 голосов
/ 01 ноября 2010

Такое ощущение, что 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 ]

6 голосов
/ 01 ноября 2010

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

0 голосов
/ 12 декабря 2012

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

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

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

...