【问题标题】:Rails, why '.to_json' is escaping html entitiesRails,为什么 '.to_json' 正在转义 html 实体
【发布时间】:2015-08-31 19:08:49
【问题描述】:

这就是rails console (Rails v4.0.4) 中发生的情况:

irb(main):020:0> "pepe&pepe <juan>".to_json
=> "\"pepe\\u0026pepe \\u003Cjuan\\u003E\""

这就是irb console (Ruby 2.0.0p247) 中发生的情况:

irb(main):014:0> "pepe&pepe <juan>".to_json
=> "\"pepe&pepe <juan>\""

我知道我可以覆盖此行为,但我担心的是为什么 Rails 默认会这样做?这可能是不这样做的后果?因为对我来说,覆盖这种行为而不是转义 html 实体看起来是个好主意,但我确信我错过了一些东西。

【问题讨论】:

    标签: ruby-on-rails ruby json escaping


    【解决方案1】:

    JSON 被写入 HTML 上下文 - 脚本和属性 - 在 Rails 中很多

    此默认转义避免在以下情况下注入:在特定上下文中有意义且未转义的字符会构成注入/XSS 风险。1

    当且仅当,在不是这种情况的上下文中处理,那么它可以被安全地禁用:默认只是倾向于“安全”。因为这种 HTML 安全转换可以 不违反任何标准并且 不链接 JSON 等效性2 这就是 Rail 的团队所做的 - 对他们有好处!3

    尤其是这样可以避免讨厌的“JSON”2,例如:

    var x = {"foo": "</script><script>alert('owned')</script>"};
    

    JSON 嵌入到其他 HTML 结构中,例如。数据属性,也可能有问题。即使使用需要额外编码步骤的JSON.parse,也会留下同样的潜在问题。


    1 标准的安全编码输出方法适用于 HTML PCDATA 上下文,但在将 JSON 发送到脚本元素 (CDATA) 的情况下,这是不可取的并且有意跳过(例如,使用 @ 987654324@).

    2 这是another answer of mine,我在其中写了关于为什么这种转义始终有效以及使用 JSON 作为 JavaScript 文字的警告。与臭名昭著且设计不当的“添加斜线”不同,HTML 安全的 JSON 表示相同的信息。

    3 Microsoft 的 JavaScriptSerializer 和 PHP 中的 json_encode 具有相似的默认编码行为。使用这些库/函数的默认上下文可能对默认的 HTML 安全配置有很大影响。

    【讨论】:

    • 我非常感谢并接受您提供的扩展答案。但是我不能同意Rails在这方面的傲慢。这个.to_json 覆盖将问题添加到在 Rails 应用程序的相同上下文中加载的通用库中。 Rails 应用程序决定将对象解析为 json 的标准 Ruby 方式现在将发生变化,因此它正在更改为使用 Rails 加载的任何库:/。我接受覆盖标准方法是个好主意并且非常有帮助,但我认为原始行为必须保持默认。
    • 来自 Microsoft 的 @fguillen JavaScriptSerializer 和来自 PHP 的 json_encode 都遵循类似的 HTML 安全默认编码。正弦编码的 JSON 是等效的 - 但文本内容不相等,从未保证 - 我对转换没有问题。在任何情况下,此类问题都会更好地发送到相应的项目主页/邮件列表。
    • @fguillen:但是 "\u003C" "&lt;" 在 JSON 和 JavaScript 中。没有兼容的 JSON 解码器应该关心差异,因为实际上没有任何差异。是的,Rails 倾向于傲慢、固执和固执己见,但这次它们真的没那么糟糕,它们仍在生成完全兼容的 JSON。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多