Как HTML кодировать / экранировать строку? Есть ли встроенный?

98

У меня есть ненадежная строка, которую я хочу показать как текст на HTML-странице. Мне нужно убежать от символов ' <' и ''& ' как объектов HTML. Чем меньше суеты, тем лучше.

Я использую UTF8, и мне не нужны другие сущности для букв с диакритическими знаками.

Есть ли встроенная функция в Ruby или Rails, или я должен использовать свою?

кч
источник
2
Согласно OWASP , следующие шесть символов должны быть экранированы для надлежащей защиты XSS в содержимом HTML-элемента:&<>"'/
sffc,

Ответы:

94

hВспомогательный метод:

<%=h "<p> will be preserved" %>
Тревор Брамбл
источник
Ну, он также экранирует>, что не нужно, но сойдет.
kch
Вы можете использовать круглые скобки, чтобы напечатать некоторые с h, а некоторые без. <% = h ("<p") + ">"%>
Тревор Брамбл,
Это было бы глупо. Меня не очень волнует, сбежит он или нет. Я просто отмечаю, что это не требуется в соответствии со спецификациями html.
kch
12
Это иногда требуется в XHTML из - за довольно раздражающей настойчивостью XML - SPEC, что «]]>» быть удалены из текста (см производство «CharData»). Это обычно упрощает (и безвредно) всегда избегает этого.
bobince
19
для интересующихся hесть псевдоним дляhtml_escape
lightswitch05
141

Ознакомьтесь с классом Ruby CGI . Существуют методы кодирования и декодирования HTML, а также URL-адресов.

CGI::escapeHTML('Usage: foo "bar" <baz>')
# => "Usage: foo &quot;bar&quot; &lt;baz&gt;"
Кристофер Брэдфорд
источник
12
Спасибо, это здорово, так как это можно сделать с контроллеров. Не то чтобы я, конечно, так поступил.
Дэн Розенстарк 02
2
Это полезно в функциональных / интеграционных тестах для проверки правильности содержимого, вставленного в шаблон (когда предполагается, что содержимое должно быть экранировано HTML).
Alex D
Если контент отображается на клиентском веб-сайте, кроме вашего собственного (где вы не можете контролировать представление), в чем проблема с экранированием html перед вставкой в ​​базу данных? Есть ли другая работа?
n00b
Справа - экранирование перед входом в базу данных - это здорово. Вы просто хотите убедиться, что у вас нет никаких старых не ускользнувших хаков до того, как вы его добавили ...
Кевин
5
Мне больше нравится его синоним: CGI.escape_html
Trantor Liu
77

В Ruby on Rails 3 HTML по умолчанию будет экранирован.

Для строк без экранирования используйте:

<%= raw "<p>hello world!</p>" %>
RSK
источник
25

ERB :: Util.html_escape можно использовать где угодно. Он доступен без использования requireв Rails.

Виктор Трон
источник
это на самом деле используется CGI.escapeHTMLвнизу
akostadinov 03
@akostadinov - результат другой. Например, ERB :: Util.html_escape превратит апострофы в & # x27; тогда как CGI :: escapeHTML не будет
Луи Сэйерс
@LouisSayers, я не понимаю, как это может случиться: «` `[43] pry (main)> show-source ERB :: Util.html_escape From: /usr/share/ruby/erb.rb @ line 945: Owner : # <Class: ERB :: Util> Видимость: public Количество строк: 3 def html_escape (s) CGI.escapeHTML (s.to_s) end `` ''
akostadinov
@akostadinov - хм ... Просто запустил еще раз и да, результат такой же. Клянусь, это дало разные результаты, когда я запускал это на работе (возможно, другое поведение версии erb / cgi?). Надо посмотреть, почему завтра на работе у меня другой результат.
Луи Сэйерс
17

В дополнение к ответу Кристофера Брэдфорда использовать экранирование HTML где угодно, поскольку большинство людей в настоящее время не используют CGI, вы также можете использовать Rack:

require 'rack/utils'
Rack::Utils.escape_html('Usage: foo "bar" <baz>')
J -_- L
источник
Есть ли лучший способ экранировать строки аналогичным образом в методах экземпляра модели?
Кодирование активировано
15

Вы можете использовать либо h()или html_escape(), но большинство людей используют h()условно. h()это сокращение отhtml_escape() рельсы.

В вашем контроллере:

@stuff = "<b>Hello World!</b>"

На ваш взгляд:

<%=h @stuff %>

Если вы просматриваете исходный HTML-код: вы увидите результат без выделения данных. Т.е. кодируется как &lt;b&gt;Hello World!&lt;/b&gt;.

Он будет отображаться как <b>Hello World!</b>

Брайан Р. Бонди
источник
9

Сравнение различных методов:

> CGI::escapeHTML("quote ' double quotes \"")
=> "quote &#39; double quotes &quot;"

> Rack::Utils.escape_html("quote ' double quotes \"")
=> "quote &#x27; double quotes &quot;"

> ERB::Util.html_escape("quote ' double quotes \"")
=> "quote &#39; double quotes &quot;"

Я написал свой собственный, чтобы быть совместимым с экранированием Rails ActiveMailer:

def escape_html(str)
  CGI.escapeHTML(str).gsub("&#39;", "'")
end
Дориан
источник
0

h() также полезно для экранирования кавычек.

Например, у меня есть представление, которое генерирует ссылку с использованием текстового поля result[r].thtitle. Текст может включать одинарные кавычки. Если бы я не сбежал result[r].thtitleс помощью метода подтверждения, Javascript сломался бы:

&lt;%= link_to_remote "#{result[r].thtitle}", :url=>{ :controller=>:resource,
:action         =>:delete_resourced,
:id     => result[r].id,
:th     => thread,                                                                                                      
:html       =>{:title=> "<= Remove"},                                                       
:confirm    => h("#{result[r].thtitle} will be removed"),                                                   
:method     => :delete %>

&lt;a href="#" onclick="if (confirm('docs: add column &amp;apos;dummy&amp;apos; will be removed')) { new Ajax.Request('/resource/delete_resourced/837?owner=386&amp;th=511', {asynchronous:true, evalScripts:true, method:'delete', parameters:'authenticity_token=' + encodeURIComponent('ou812')}); }; return false;" title="&lt;= Remove">docs: add column 'dummy'</a>

Примечание: :htmlобъявление заголовка волшебным образом экранируется Rails.

Ноддинов
источник