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

Предотвращение того, чтобы символы HTML-символов в файлах локалей не попадали в Rails3 xss-защиту

Мы создаем приложение, наше первое использование Rails 3, и нам нужно сначала построить I18n. Будучи перфекционистами, мы хотим, чтобы в наших представлениях использовалась настоящая типография: тире, завитые цитаты, эллипсы и др.

Это означает, что в наших файлах locals/xx.yml есть два варианта:

  • Используйте реальные символы UTF-8 в строке. Должен работать, но трудно печатать, и меня пугает из-за количества программное обеспечение, которое все еще делает озорной вещи в unicode.
  • Использовать HTML символьные объекты (& # 8217; & Амп; # 8212; и т.д). Легче печатать, и, вероятно, более совместимы с неправильное программное обеспечение.

Я предпочел бы воспользоваться вторым вариантом, однако автоматическое экранирование в Rails 3 делает эту проблему проблематичной, поскольку амперсанды в YAML автоматически преобразуются в объекты символов, что приводит к "видимым" и 8217; браузера.

Очевидно, это можно обойти, используя raw в строках, то есть:

raw t('views.signup.organisation_details')

Но мы не счастливы спуститься по всему миру raw -ing каждый раз, когда мы t что-то, поскольку оно оставляет нас открытыми для создания ошибки и создания дыры XSS.

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

Любые предложения по умным рельсам-y, чтобы исправить это? Или мы обречены печатать типографию, xss дыры, часы потраченного впустую усилия или все это?

4b9b3361

Ответ 1

Для этой проблемы существует билет в маяке, и разрешение заключается в добавлении _html к ключу i18n в locales/xx.yml и используйте псевдоним t 1 чтобы обозначить строку html_safe. Например:

en:
  hello: "This is a string with an accent: ó"

становится:

en:
  hello_html: "This is a string with an accent: ó"

И он создаст следующий вывод:

Это строка с акцентом: & oacute;

Это помешает вам написать raw t('views.signup.organisation_details') и приведет к более чистым выводам: t('views.signup.organisation_details_html'). И при обмене raw на _html не кажется величайшей сделкой, он ясно показывает, что вы выводите то, что считается строкой html_safe.


1 Я протестировал код, предложенный в маяке. Я обнаружил, что вам нужно было использовать псевдоним t. Если вы использовали I18n.t или I18n.translate, перевод не рассматривал _html как html_safe:
I18n.t('hello_html') 
I18n.translate('hello_html') 
# Produces => "This is a string with an accent: ó"

t('hello_html')      
# Produces => "This is a string with an accent: ó"

Я не думаю, что это предполагаемое поведение в документации RoR TranslationHelper.

Ответ 2

Ну. Вчера я поставил этот вопрос из-за угла i18n, но не ответил на него, поскольку я человек Python, который никогда не использовал Rails. Я все равно не собираюсь отвечать на него, но, учитывая, что вы не наводнены полезными Railsians, которые могли бы указать вам на хороший способ обойти внутренности Rails, здесь, тем не менее, моя перспектива.

Прежде всего, я считаю, что с самого начала вы думаете о проблеме. Это довольно редко. Во-вторых, я полностью согласен с тем, что использование необработанных строк или выборочная выборка строк с сущностями, чтобы дать особое обращение к звукам, как хрупкий, уродливый, подверженный ошибкам хак.

Теперь, если я правильно понимаю Rails (я читаю это руководство i18n), файлы YAML содержат локализованную строку для каждого языка. В этом случае я настоятельно рекомендую использовать в них обычные символы (в UTF-8). В противном случае, сохранение локализации или даже чтение через файл перевода - подумайте о языках в нелатинских скриптах! - будет ад.

Да, это будет означать, что вам нужно выяснить методы ввода, но решение чистое и простое.

Ответ 3

Если вы не хотите раскрывать возможность ошибки простым добавлением .html_safe (через alias_method_chain или w/e) ко всему, лучшим решением является просто использовать его всякий раз, когда это необходимо.

На нашем сайте мы используем язык разметки, чтобы получить вывод HTML из файлов локали i18n, так как кто переводит эти файлы, это не разработчики, а просто переводчики.

Если только на нескольких местах вам нужен HTML-код, который действительно будет HTML, используйте .html_safe

t('views.signup.organisation_details').html_safe

Простой язык разметки, который у нас работает, очень хорошо для нас, но это действительно специфично для конкретного случая:)

Ответ 4

Знаете ли вы о методе html_safe, который можно использовать в помощниках? Я не уверен, что я полностью понимаю проблему здесь, так как я никогда не работал с I18n, но можно ли использовать специальный помощник, который определяет, не должны ли экранироваться символы и возвращать "string".html_safe, и если это бежать, вернуть "строку".

Или, возможно, переопределить хелпер "t" и добавить свои логические условия экранирования +.html_safe

Ответ 5

Я думаю, что не рекомендуется использовать "raw", вы можете попробовать с yml-строкой, подобной этой

en:
  hello:
    This generates a text paragraph for HTML. " " à @ ' All this text, which you can find in
    these lines, is being concatenated together to one single text node, and then put
    into the body of the <p> ... </p> tag. ↂↀऊᎣᏍᏮ⁜℺℻⊛⍟⎬⎨⏏♞♝⚫⚬✱✰✭❺❻➣➱➲⬡⬕

HTML

This generates a text paragraph for HTML. &quot; &quot; à @ ' All this text, which you can find in these lines, is being concatenated together to one single text node, and then put into the body of the &lt;p&gt; ... &lt;/p&gt; tag. ↂↀऊᎣᏍᏮ⁜℺℻⊛⍟⎬⎨⏏♞♝⚫⚬✱✰✭❺❻➣➱➲⬡⬕

просмотр браузера

This generates a text paragraph for HTML. " " à @ ' All this text, which you can find in these lines, is being concatenated together to one single text node, and then put into the body of the <p> ... </p> tag. ↂↀऊᎣᏍᏮ⁜℺℻⊛⍟⎬⎨⏏♞♝⚫⚬✱✰✭❺❻➣➱➲⬡⬕