15

导轨 3:

{"a" => "<br/>"}.to_json
=> "{\"a\":\"<br/>\"}"

导轨 4:

{"a" => "<br/>"}.to_json
=> "{\"a\":\"\\u003Cbr/\\u003E\"}"

为什么???

它似乎导致了错误

Encoding::UndefinedConversionError: "\xC3" from ASCII-8BIT to UTF-8

当我的 Rails 3 应用程序尝试解析我的 rails 4 应用程序生成的 JSON 时。

4

3 回答 3

14

为什么???

防御 Web 应用程序中的常见弱点。如果您在 HTML 页面中说,例如:

<script type="text/javascript">
    var something = <%= @something.to_json.html_safe %>;
</script>

那么你可能会认为你很好,因为你已经对你注入 JavaScript 的数据进行了 JSON 转义。但实际上你并不安全:除了 JSON 语法之外,你还有 HTML 语法,并且在 HTML 脚本块</中是带内信号。实际上,如果@something包含字符串</script>,您就会遇到跨站点脚本漏洞:

<script type="text/javascript">
    var something = {"attack": "abc</script><script>alert('XSS');//"};
</script>

第一个脚本块在字符串的中途结束(留下未闭合的字符串文字语法错误),第二个<script>脚本块被视为新的脚本块,并执行其中的潜在用户提交的内容。

JSON 不需要将<字符转义为,但它是一种完全有效的替代方法,它会自动避免此类问题。\u003C如果 JSON 解析器拒绝它,那是阅读器中的一个严重错误。

产生该错误的代码是什么?我不相信该错误与<-转义有关,因为它谈论的是字节0xC3而不是0x3C。这可能表明一个带有 UTF-8 编码内容的字符串没有被标记为 UTF-8……也许你需要force_encoding("UTF-8")在输入上加上一个?

于 2013-07-30T11:37:51.863 回答
8

您可以保留原始字符串JSON::dump

JSON::dump "a" => "<br/>"
=> "{\"a\":\"<br/>\"}"

JSON::dump "a" => "x&y"
=> {\"a\":\"x&y\"}" # instead of x\u0026y

由于 bobince 提到的原因,请谨慎使用它,尤其是避免使用任何用户生成的输入(或至少确保已清理)。

这是我遇到的一个合法使用的例子。在辅助函数中生成 JavaScript 哈希参数:

# application_helper.rb

def widget_js(post)
  options = {
    color: ColorCalculator(post.color).to_rgb_hex,
    ...
  }
  "third_party_widget(#{JSON::dump options});"
end
于 2015-04-04T10:06:50.127 回答
1

我也遇到了这个问题,正如其他人所提到的,它是由使用 ActiveSupport to_json 方法引起的。要解决此问题,请直接将 JSON gem 与 JSON.generate(data) 一起使用,其中 data 是一个数组或哈希。有关所有 JSON gem 文档,请参阅https://github.com/flori/json

于 2021-02-04T10:31:53.313 回答