Rails3 и безопасный nl2br!

У меня есть система, позволяющая пользователям оставлять комментарии.

Комментарии захватываются в текстовое поле.

Моя проблема заключается в форматировании комментариев с тегом br для замены \n

На самом деле, я мог бы сделать что-то вроде этого

s.gsub(/\n/, '<br />')

Но защита xss, в том числе и в рельсах, пропускает ярлыки br.

Так что я мог бы сделать это

s.gsub(/\n/, '<br />').html_safe

Но тогда все теги принимаются даже script.... вызывают большую проблему с безопасностью

Итак, мой вопрос: как форматировать текст с br безопасно?

Спасибо

EDIT: На данный момент я добавляю это

  def sanitaze
    self.gsub(/(<.*?>)/, '')
  end

  def nl2br
    self.sanitaze.gsub(/\n/, '<br />').html_safe
  end

Ответы

Ответ 1

Как сказал Райан Бигг, simple_format - лучший инструмент для работы: он безопасен и намного опрятен, чем другие решения.

поэтому для @var:

<%= simple_format(@var) %>

Если вам нужно очистить текст, чтобы избавиться от HTML-тегов, вы должны сделать это, прежде чем передавать его на simple_format

http://api.rubyonrails.org/classes/ActionView/Helpers/TextHelper.html#method-i-simple_format

Ответ 2

Лучшим способом, который я могу решить, является использование метода sanitize для удаления всех, кроме тега BR, который мы хотим.

Предположим, что мы имеем @var с содержимым "some\ntext":

Попытка <%= @var.gsub(/\n/, '<br />') %> не работает.

Попытка <%= h @var.gsub(/\n/, '<br />').html_safe %> не работает и небезопасна.

Попытка <%= sanitize(@var.gsub(/\n/, '<br />'), :tags => %w(br) %> РАБОТЫ.

Я не очень хорошо это испытал, но он позволяет тегу BR работать, и заменил фиктивный script alert, который я добавил с пробелом, поэтому он, похоже, выполняет свою работу. Если кто-то еще имеет идею или может сказать, является ли это безопасным решением, пожалуйста, сделайте.

Update:

Другая идея, предложенная Хосе Валимом:

<%= h(@var).gsub(/\n/, '<br />') %> Работает

Ответ 3

Здесь что я сделал:

module ApplicationHelper
  def nl2br s
    sanitize(s, tags: []).gsub(/\n/, '<br>').html_safe
  end
end