Evitar que las entidades de caracteres HTML en los archivos de configuración regional sean munged por Rails3 xss protection


Estamos construyendo una app, nuestra primera usando Rails 3, y tenemos que construir I18n desde el principio. Siendo perfeccionistas, queremos que la tipografía real se utilice en nuestras vistas: guiones, comillas rizadas, elipses et al.

Esto significa que en nuestros archivos locales/xx.yml tenemos dos opciones:

  1. Utilice caracteres UTF-8 reales en línea. Debe funcionar, pero difícil de escribir, y me asusta debido a la cantidad de software que todavía hace travieso cosas para unicode.
  2. Usar HTML caracter entidad (’ - sucesivamente). Más fácil de escribir, y probablemente más compatible con software de mala conducta.

Prefiero tomar la segunda opción, sin embargo, el escape automático en Rails 3 hace que esto sea problemático, ya que los ampersand en el YAML se convierten automáticamente en entidades de caracteres, lo que resulta en &8217;s 'visibles' en el navegador.

Obviamente esto se puede trabajar usando raw en cadenas, es decir:

raw t('views.signup.organisation_details')

Pero no estamos contentos de ir por la ruta de lo global raw - ing cada vez que t algo nos deja abiertos a cometer un error y producir un agujero XSS.

Podríamos selectivamente raw cadenas que sabemos que contienen entidades de carácter, pero esto sería difícil de escalar, y simplemente se siente mal - además, una cadena que contiene una entidad en un idioma puede no ser en otro.

¿Alguna sugerencia sobre una manera inteligente de rails-y para solucionar esto? ¿O estamos condenados a la tipografía de mierda, agujeros xss, horas de esfuerzo desperdiciado o todo eso?

Author: Chris S, 2010-08-13

5 answers

Hay un ticket en lighthouse para este problema, y la resolución es anexar _html a la clave i18n en el archivo locales/xx.yml y usar el alias t 1 para denotar una cadena html_safe. Por ejemplo:

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

Se convierte en:

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

Y crearía la siguiente salida:

Esta es una cuerda con acento: ó{[21]]}

Esto evitaría que tenga que escribir raw t('views.signup.organisation_details') y resultaría en una salida más limpia de: t('views.signup.organisation_details_html'). Y mientras que intercambiar raw por _html no parece ser el mejor de los oficios, deja las cosas claras que está produciendo lo que se supone que es una cadena html_safe.


1 He probado el código sugerido en el billete del faro. Lo que encontré fue que tenías que usar específicamente el alias t. Si usaste I18n.t o I18n.translate la traducción no trató a _html como 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: ó"

No creo que este sea el comportamiento previsto por el RoR TranslationHelper documentation.

 32
Author: Gavin Miller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-10 19:12:57

Bueno. Marcé esta pregunta ayer debido al ángulo i18n, pero no la respondí ya que soy una persona de Python que nunca ha usado Rails. Todavía no voy a responder, pero dado que no estás siendo invadido por Railsians útiles que podrían señalarte una buena manera de sortear las entrañas de Rails, aquí está mi perspectiva, no obstante.

En primer lugar creo que es genial que estés pensando en el problema desde el principio. Eso es bastante raro. Segundo, estoy completamente de acuerdo en que usar cuerdas crudas o seleccionar selectivamente cuerdas con entidades para dar un tratamiento especial a los sonidos como un truco quebradizo, feo y propenso a errores.

Ahora si entiendo Rails correctamente (he leído esta guía i18n), los archivos YAML contienen la cadena localizada para cada idioma. En este caso, recomiendo encarecidamente usar caracteres regulares en ellos (en UTF-8). De lo contrario, mantener las localizaciones, o incluso leer a través de un archivo de traducción think piense en idiomas no latinos ¡guiones! -- va a ser un infierno.

Sí, significaría que tienes que averiguar los métodos de entrada, pero la solución es limpia y sencilla.

 8
Author: chryss,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-15 13:20:44

Si no quieres exponerte a la posibilidad de un error por simple adición .html_safe (a través de alias_method_chain o w / e) a todo, la mejor solución es simplemente usarlo siempre que sea necesario.

En nuestro sitio utilizamos el lenguaje de marcado para obtener la salida HTML de los archivos de configuración regional de i18n, ya que quienes traducen esos archivos no son desarrolladores, solo traductores.

Si es solo en unos pocos lugares donde necesita que su HTML sea realmente HTML, use .html_safe

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

El simple el lenguaje de marcado que tenemos funciona bastante bien para nosotros, pero eso es realmente específico para cada caso:)

 1
Author: Draiken,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-10 12:04:48

¿Conoce el método html_safe que se puede usar en helpers? No estoy seguro de si entiendo totalmente el problema aquí, ya que nunca he trabajado con I18n, pero sería posible utilizar un ayudante personalizado que determina si los caracteres no deben escaparse y devolver "cadena".html_safe, y si debe ser escapado, retorno "cadena".

O posiblemente sobreescriba el ayudante "t" y agregue sus condiciones lógicas de escape + .html_safe

 0
Author: johnmcaliley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-16 01:36:42

Creo que no es una buena idea usar use "raw", podría probar con una cadena yml como esta

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. ↂↀऊᎣᏍᏮ⁜℺℻⊛⍟⎬⎨⏏♞♝⚫⚬✱✰✭❺❻➣➱➲

Vista del navegador

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
Author: grigio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-27 14:37:12