Предотвращение использования объектов символов HTML в файлах локали с помощью Rails3 xss protection - PullRequest
26 голосов
/ 13 августа 2010

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

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

  1. Используйте настоящие символы UTF-8. Должен работать, но трудно набрать, и пугает меня из-за количества программное обеспечение, которое до сих пор делает непослушный вещи в юникоде.
  2. Использовать HTML персонажи (’ - так далее). Легче набрать, и, вероятно, более совместим с плохо себя ведущий софт.

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

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

raw t('views.signup.organisation_details')

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

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

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

Ответы [ 5 ]

32 голосов
/ 10 января 2011

Для решения этой проблемы в маяке есть билет *1002*, и необходимо добавить _html к ключу i18n в файле locales/xx.yml и использовать псевдоним t * 1007. * 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 .

8 голосов
/ 15 августа 2010

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

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

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

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

1 голос
/ 10 января 2011

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

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

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

0 голосов
/ 27 ноября 2010

Я думаю, что не стоит использовать «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. ↂↀऊᎣᏍᏮ⁜℺℻⊛⍟⎬⎨⏏♞♝⚫⚬✱✰✭❺❻➣➱➲⬡⬕
0 голосов
/ 16 августа 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...