给定类 JSON 内容,JSON Sanitizer 会将其转换为有效的 JSON。
它可以附加在数据处理管道的任意一端,以帮助满足 Postel 原则:
对自己要保守,对别人要宽容
应用于来自他人的类 JSON 内容时,它将生成符合规范的 JSON,可满足您使用的任何解析器。
应用于发送前的输出时,它将纠正编码中的小错误,并使您的 JSON 更易于嵌入 HTML 和 XML。

许多应用程序有大量代码使用临时方法生成 JSON 输出。
这些输出通常都会经过一小部分框架代码,然后通过网络发送。这一小部分框架代码可以使用本库确保临时输出符合标准且安全,可传递给功能过于强大的反序列化器(如 JavaScript 的 eval 运算符)。
应用程序还经常有接收来自多种来源的 JSON 的 Web 服务 API。当这些 JSON 使用临时方法创建时,本库可以将其整理成易于解析的形式。
通过将本库挂接到发送和接收请求及响应的代码中,本库可以帮助软件架构师确保系统范围的安全性和良好格式。
Sanitizer 接收类 JSON 内容,并像 JS eval 那样解释它。具体来说,它处理以下非标准结构。
| 构造 | 策略 |
|---|---|
'...' | 单引号字符串转换为 JSON 字符串。 |
\xAB | 十六进制转义转换为 JSON Unicode 转义。 |
\012 | 八进制转义转换为 JSON Unicode 转义。 |
0xAB | 十六进制整数字面量转换为 JSON 十进制数字。 |
012 | 八进制整数字面量转换为 JSON 十进制数字。 |
+.5 | 十进制数字被强制转换为 JSON 更严格的格式。 |
[0,,2] | 数组中的省略部分用 null 填充。 |
[1,2,3,] | 删除尾部逗号。 |
{foo:"bar"} | 未加引号的属性名被加上引号。 |
//comments | 移除 JS 风格的行注释和块注释。 |
(...) | 移除分组括号。 |
Sanitizer 会修正缺少的标点、结束引号以及不匹配或缺少的右括号。如果输入仅包含空白字符,则替换为有效的 JSON 字符串 null。
输出是符合 RFC 4627 定义的格式良好的 JSON。输出还满足以下附加属性:
"</script",因此无需额外编码即可嵌入 HTML script 元素中。"]]>",因此无需额外编码即可嵌入 XML CDATA 段中。eval 内置函数(包裹在括号中)或 JSON.parse 进行解析。具体来说,输出不会包含任何嵌入的 JS 换行符(U+2028 段落分隔符或 U+2029 行分隔符)的字符串字面量。由于输出是格式良好的 JSON,将其传递给 eval 将没有副作用和自由变量,因此既不是代码注入的向量,也不是秘密泄露的向量。
本库仅确保 JSON 字符串 → JavaScript 对象阶段没有副作用且不解析自由变量,无法控制后续客户端代码如何解释生成的 JavaScript 对象。因此,如果客户端代码将解析数据中由攻击者控制的部分通过 eval 或 innerHTML 等强大解释器再传回,则可能产生意外的副作用。
var myValue = eval(sanitizedJsonString); // 安全
var myEmbeddedValue = eval(myValue.foo); // 可能不安全
此外,清理 JSON 并不能保护应用程序免受混淆代理攻击。
var myValue = JSON.parse(sanitizedJsonString);
addToAdminstratorsGroup(myValue.propertyFromUntrustedSource);
当输入已是满足上述属性的有效 JSON 时,sanitize 方法将直接返回输入字符串而不分配新的缓冲区。因此,如果用于通常格式良好的输入,内存开销最小。
sanitize 方法的时间复杂度为 O(n),其中 n 是输入的 UTF-16 代码单元长度。