防止区域设置文件中的HTML字符实体被Rails3 xss保护屏蔽

防止区域设置文件中的HTML字符实体被Rails3 xss保护屏蔽,html,ruby-on-rails,internationalization,ruby-on-rails-3,xss,Html,Ruby On Rails,Internationalization,Ruby On Rails 3,Xss,我们正在构建一个应用程序,这是我们第一次使用Rails 3,而且我们必须从一开始就将I18n构建进来。作为完美主义者,我们希望在我们的视图中使用真正的字体:破折号、卷曲引号、省略号等 这意味着在locales/xx.yml文件中,我们有两种选择: 内联使用真正的UTF-8字符。 应该可以,但是很难打字,而且 由于数量太多,我很害怕 软件仍然很顽皮 将所有内容转换为unicode 使用HTML 字符实体(’; —;等等)。更容易打字, 而且可能更符合 行为不端的软件 我宁愿选择

我们正在构建一个应用程序,这是我们第一次使用Rails 3,而且我们必须从一开始就将I18n构建进来。作为完美主义者,我们希望在我们的视图中使用真正的字体:破折号、卷曲引号、省略号等

这意味着在locales/xx.yml文件中,我们有两种选择:

  • 内联使用真正的UTF-8字符。 应该可以,但是很难打字,而且 由于数量太多,我很害怕 软件仍然很顽皮 将所有内容转换为unicode
  • 使用HTML 字符实体(’; —;等等)。更容易打字, 而且可能更符合 行为不端的软件
  • 我宁愿选择第二个选项,但是Rails 3中的自动转义使这一点成为问题,因为YAML中的符号会自动转换为字符实体,从而导致“可见”&8217;它在浏览器中

    显然,这可以通过在字符串上使用
    raw
    来解决,即:

    raw t('views.signup.organisation_details')
    
    但是,我们不愿意在每次我们做某事的时候都进行全局
    raw
    -ing,因为这会让我们容易出错并产生XSS漏洞

    我们可以选择
    raw
    字符串,我们知道这些字符串包含字符实体,但这很难扩展,而且感觉不对——此外,一种语言中包含实体的字符串可能不包含另一种语言中的实体


    有没有关于一个聪明的rails-y方法来解决这个问题的建议?还是我们注定要浪费排版、xss漏洞、数小时的努力还是所有这些。由于i18n的角度,我昨天将这个问题添加到书签中,但没有回答,因为我是一个Python爱好者,从未使用过Rails。我仍然不打算回答这个问题,但考虑到你没有被乐于助人的Rails人所超越,他们可以为你指出一种绕过Rails内部的好方法,这里还是我的观点

    首先,我认为你从一开始就考虑这个问题是很好的。那是相当罕见的。第二,我完全同意使用原始字符串或有选择地拾取带有实体的字符串来对听起来像是脆弱、丑陋、容易出错的黑客进行特殊处理

    现在,如果我正确理解了Rails(我读过),YAML文件包含每种语言的本地化字符串。在这种情况下,我强烈建议在它们中使用正则字符(在UTF-8中)。否则,维护本地化,甚至阅读翻译文件——想想非拉丁语脚本中的语言将会是地狱


    是的,这意味着您必须找出输入法,但解决方案是简洁明了的。

    您知道可以在助手中使用的html\u安全方法吗?我不确定我是否完全理解这里的问题,因为我从未使用过I18n,但是否可以使用自定义帮助程序来确定字符是否不应转义并返回“string”。html_safe,如果应该转义,则返回“string”


    或者可能重写“t”帮助程序并添加转义逻辑条件+.html\u safe

    我认为使用“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. ↂↀऊᎣᏍᏮ⁜℺℻⊛⍟⎬⎨⏏♞♝⚫⚬✱✰✭❺❻➣➱➲⬡⬕
    
    t('views.signup.organisation_details').html_safe
    
    浏览器视图

    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生成一个文本段落。“在这些行中可以找到的所有文本都被连接到一个文本节点上,然后放入的主体中。”

    标签。ↂↀऊᎣᏍᏮ⁜℺℻⊛⍟⎬⎨⏏♞♝⚫⚬✱✰✭❺❻➣➱➲⬡⬕
    这个问题有一个解决方案,解决方案是将
    \u html
    附加到
    locales/xx.yml
    文件中的i18n键,并使用
    t
    别名1表示html安全字符串。例如:

    en:
      hello: "This is a string with an accent: &oacute;"
    
    变成:

    en:
      hello_html: "This is a string with an accent: &oacute;"
    
    它将创建以下输出:

    这是一个带重音的字符串:ó

    这将避免您必须编写
    raw t('views.signup.organization\u details')
    ,并将导致更清晰的输出:
    t('views.signup.organization\u details\u html')
    。虽然用
    raw
    交换
    \u html
    似乎不是最伟大的交易,但它确实清楚地表明,您输出的是假定为html\u安全字符串的内容


    1我已经测试了灯塔票中建议的代码。我发现您必须特别使用
    t
    别名。如果使用了
    I18n.t
    I18n.translate
    翻译,则翻译不会将
    \u html
    视为html安全:

    I18n.t('hello_html') 
    I18n.translate('hello_html') 
    # Produces => "This is a string with an accent: &oacute;"
    
    t('hello_html')      
    # Produces => "This is a string with an accent: ó"
    

    我不认为这是预期的行为。

    如果您不想通过简单地将.html\u safe(通过别名\u方法\u链或w/e)添加到所有内容中而暴露出错误的可能性,那么最好的解决方案就是在必要时使用它

    在我们的站点中,我们使用标记语言从i18n语言环境文件中获取HTML输出,因为翻译这些文件的不是开发人员,而是翻译人员

    如果只有少数地方需要HTML真正成为HTML,请使用.HTML\u safe

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

    我们使用的简单标记语言对我们来说非常有效,但这确实是特定于具体情况的:)

    这是一个好问题。期待一个好的答案。我自己对这个问题(以及“铁路之路”)了解不够,不知道这是一个好计划还是另一条毁灭之路,但谢谢你的想法。。。可能会尝试一下,让您知道它是如何运行的。是的,只需将完整的UTF-8编码字符放在文件中。这就是自恐龙时代以来Java人一直在做的事情——查看他们所有的language.properties文件,您将看到本地编码。回顾过去,我认为这可能是最好的解决方案。我不知道为什么三年前我对它如此反感。