Почему в Rails 3 <% = note.html_safe%> и <% = h note.html_safe%> дают одинаковый результат?
Похоже на html_safe
добавляет абстракцию к классу String, который требует понимания того, что происходит, например,
<%= '1 <b>2</b>' %> # gives 1 <b>2</b> 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 <b>2</b> wont' escape twice
Для строки 4, если мы говорим, хорошо, мы доверяем строке - это безопасно, но почему мы не можем избежать этого? Кажется, чтобы избежать этого путем h
Строка должна быть небезопасной.
Так в строке 1, если строка не экранирована h
, он будет автоматически экранирован. В строке 5 h
не может дважды покинуть строку - другими словами, после <
изменено на <
, это не может избежать этого еще раз &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
Любые операции над SafeBuffer, которые могут повлиять на безопасность строки, будут переданы через h ()
h использует этот флаг, чтобы избежать двойного побега
Поведение изменилось, и я думаю, что вы в основном правы о том, как это работает. В общем, вы не должны вызывать html_safe, если вы не уверены, что он уже очищен. Как и все, вы должны быть осторожны при использовании
В рельсах 3 весь вывод использует h
помощник по умолчанию
см. http://origami.co.uk/blog/2010/02/rails-3-html-escaping
если вы не хотите убежать, вы можете использовать raw