Как сделать ссылки html безопасными и игнорировать другие теги html в Rails - PullRequest
0 голосов
/ 14 апреля 2020

У меня есть требование, когда мне нужно сделать ссылки кликабельными в тексте, сохраняя при этом любые другие теги html в виде текста (не html_safe). Это означает, что я не могу сделать весь текст html_safe, так как он будет отображать другие теги html, и я не могу очистить текст и удалить другие теги html. Я видел, как другие сайты справляются с этим, создавая ссылки html_safe и другой текст в своих строках. При проверке html.

<span>
  "This is an "
  <a href="https://example.com/" target="_blank" rel="nofollow">https://example.com/</a> 
  "other <b>HTML</b>"
</span>

это выглядит следующим образом. Как лучше всего это сделать в Rails 4?

Ответы [ 2 ]

1 голос
/ 14 апреля 2020

Когда вы вызываете .html_safe для строки, вы фактически получаете объект, который ведет себя как строка, но является ActiveSupport::SafeBuffer. Когда вы добавляете строку к ActiveSupport::SafeBuffer, она автоматически экранируется. Допустим, вы хотите построить диапазон, в котором текст вводится пользователем:

'<span>'.html_safe + text +'</span>'.html_safe

В этом случае мы защищены от атаки XXS, поскольку исходный текст пользователя автоматически экранируется:

irb(main):004:0> "<span>".html_safe + "<script>alert('You have been haxxored!')</script>" + "</span>".html_safe
=> "<span>&lt;script&gt;alert(&#39;You have been haxxored&#39;)&lt;/script&gt;</span>"

Вот что происходит автоматически, когда вы выводите переменную в своих представлениях, поскольку представление построено как ActiveSupport::SafeBuffer. Всякий раз, когда вы выводите обычную строку, она автоматически экранируется, поэтому по умолчанию она защищена.

Конечно, всегда найдется огромное количество программистов, которые просто дадут возможность самим сделать XSS-уязвимость по незнанию:

# WAAAH! Rails is escaping my tags! Bad rails!
'<span>'+ text +'</span>'.html_safe

Другой способ решения этой проблемы - использовать помощники тегов, частичные или Nokogiri вместо использования конкатенации строк для создания HTML, что само по себе утомительно, не читается на границе и подвержено ошибкам.

0 голосов
/ 16 апреля 2020

Я смог заставить это работать, используя следующее.

  #module ApplicationHelper
  def url_regexp
    @url_regexp ||= %r{
      (?:(?:https?|ftp|file):\/\/|www\.|ftp\.)
      (?:\([-A-Z0-9+&@#\/%=~_|$?!:,.]*\)|
           [-A-Z0-9+&@#\/%=~_|$?!:,.])*
      (?:\([-A-Z0-9+&@#\/%=~_|$?!:,.]*\)|
            [A-Z0-9+&@#\/%=~_|$])
    }ix
  end

  #in the view
    <%- "This is a test https://example.com".partition(url_regexp).each do |text| %>
      <%- if text =~ url_regexp %>
        <%= "<a href='#{text}' target='_blank'>#{text}</a>".html_safe %>
      <%- else %>
        <%= text %>
    <% end %>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...