Подтвердить что ты не робот

Экранирование HTML в Rails

Каков рекомендуемый способ избежать HTML для предотвращения уязвимостей XSS в приложениях Rails?

Если вы разрешаете пользователю помещать любой текст в базу данных, но избегать его при его отображении? Должны ли вы добавлять фильтры before_save, чтобы избежать ввода?

4b9b3361

Ответ 1

Существует три основных подхода к этой проблеме.

  • используйте h() в своих представлениях. Недостатком здесь является то, что если вы забудете, вы получите pwnd.
  • Используйте плагин, который избегает содержимого при его сохранении. Мой плагин xss_terminate делает это. Тогда вам не нужно использовать h() в своих представлениях (в основном). Есть и другие, которые работают на уровне контроллера. Недостатки здесь: (a) если есть ошибка в коде экранирования, вы можете получить XSS в своей базе данных; и (b) Существуют угловые случаи, когда вы все равно захотите использовать h().
  • Используйте плагин, который экранирует содержимое при его отображении. CrossSiteSniper, вероятно, самый известный из них. Это псевдонизирует ваши атрибуты, чтобы при вызове foo.name он избегал содержимого. Там есть способ обойти его, если вам нужно, чтобы контент не был сохранен. Мне нравится этот плагин, но я не одинок в том, чтобы позволить XSS в мою базу данных в первую очередь...

Тогда есть несколько гибридных подходов.

Нет причин, по которым вы не можете одновременно использовать xss_terminate и CrossSiteSniper.

Существует также реализация ERb под названием Erubis, которая может быть сконфигурирована так, чтобы любой вызов типа <%= foo.name %> был экранирован - эквивалент <%= h(foo.name) %>. К сожалению, Erubis всегда, кажется, отстает от Rails, и поэтому использование этого может замедлить вас.

Если вы хотите прочитать больше, я написал сообщение в блоге (к которому Хавор любезно связался) о с помощью xss_terminate.

Ответ 2

h является псевдонимом для html_escape, который является утилитарным методом для экранирования всех символов HTML-тегов:

html_escape('<script src=http://ha.ckers.org/xss.js></script>')
# => &lt;script src=http://ha.ckers.org/xss.js&gt;&lt;/script&gt;

Если вам нужно больше контроля, перейдите к sanitize, который может использоваться как белый список тегов и атрибутов чтобы:

sanitize(@article.body, :tags => %w(table tr td), :attributes => %w(id class style))

Я бы разрешил пользователю вводить что-либо, хранить его как есть в базе данных и убегать при его отображении. Таким образом, вы не потеряете введенную информацию. Вы всегда можете настроить алгоритм ускорения...

Ответ 3

Используйте метод h в вашем шаблоне просмотра. Скажем, у вас есть объект post с свойством comment:

<div class="comment">
    <%= h post.comment %>
</div>

Ответ 5

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