使用不带引号的键安全地解析 JSON 字符串
json2.js 严格要求所有对象键都用双引号引起来。然而,在 Javascript 语法中 {"foo":"bar"}
相当于 {foo:"bar"}
。
我有一个文本区域,它接受用户的 JSON 输入,并希望“放松”对双引号键的限制。我研究了 json2.js 在评估 JSON 字符串之前如何分四个阶段验证它。我能够添加第五阶段以允许未加引号的密钥,并且想知道此逻辑是否存在任何安全隐患。
var data = '{name:"hello", age:"23"}';
// Make sure the incoming data is actual JSON
// Logic borrowed from http://json.org/json2.js
if ( /^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@")
.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]")
.replace(/(?:^|:|,)(?:\s*\[)+/g, ":") // EDITED: allow key:[array] by replacing with safe char ":"
/** everything up to this point is json2.js **/
/** this is the 5th stage where it accepts unquoted keys **/
.replace(/\w+\s*\:/g, ":")) ) { // EDITED: allow any alphanumeric key
console.log( (new Function("return " + data))() );
}
else {
throw( "Invalid JSON: " + data );
}
json2.js is strict requiring all object keys be double-quoted. However, in Javascript syntax {"foo":"bar"}
is equivalent to {foo:"bar"}
.
I have a textarea that accepts JSON input from the user and would like to "ease" the restriction on double quoting the keys. I've looked at how json2.js validates a JSON string in four stages before it evals it. I was able to add a 5th stage to allow unquoted keys and would like to know if there are any security implications to this logic.
var data = '{name:"hello", age:"23"}';
// Make sure the incoming data is actual JSON
// Logic borrowed from http://json.org/json2.js
if ( /^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@")
.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]")
.replace(/(?:^|:|,)(?:\s*\[)+/g, ":") // EDITED: allow key:[array] by replacing with safe char ":"
/** everything up to this point is json2.js **/
/** this is the 5th stage where it accepts unquoted keys **/
.replace(/\w+\s*\:/g, ":")) ) { // EDITED: allow any alphanumeric key
console.log( (new Function("return " + data))() );
}
else {
throw( "Invalid JSON: " + data );
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
这将替换参数名称上的任何单引号,并添加任何缺少的单引号。
That will replace any single quotes on the parameter name, and add any that are missing.
使用
JSON5.parse
JSON5 是 JSON 的超集,允许 ES5 语法,包括 不带引号的属性键。 JSON5 参考实现 (
json5
npm package) 提供了一个JSON5
对象,其方法与内置JSON
对象具有相同的参数和语义。许多知名项目都使用 JSON5:
Use
JSON5.parse
JSON5 is a superset of JSON that allows ES5 syntax, including unquoted property keys. The JSON5 reference implementation (
json5
npm package) provides aJSON5
object that has the same methods with the same args and semantics as the built-inJSON
object.JSON5 is used by many high profile projects:
JSON 不允许不带引号的键。 JSON 是 JavaScript 表示法的子集,不包括不带引号的键。将不带引号的键传递给几乎任何 JSON 解析器都可能会抛出错误或返回“意外”结果。
希望这有帮助
JSON does not allow unquoted keys. JSON is a subset of JavaScript notation, and that does not include unquoted keys. Passing unquoted keys to just about any JSON parser will likely throw an error or return "unexpected" results.
Hope this helps
也许你可以使用:
Maybe you can use:
下面的代码片段会将大部分类似 js 的结构转换为有效的 JSON 语法。虽然比其他答案更扩展一些,但回报是更简洁的结果。在解析无法应用的情况下,我们将优雅地失败,将错误打印到控制台并返回原始输入。
Example
Flems Playground
< strong>功能
✓ 省略任何尾随逗号。
✓ 转义字符串中的换行符。
✓ 处理数组
[]
条目,将出现的字母数字转换为字符串。✓ 保留
true
或false
的布尔值。✓ 保留
number
或float
出现。代码
分解
以下是所发生情况的简要概述:
true
和false
中删除双引号JSON.parse
免责声明
通常应该避免使用正则表达式转换字符串 json~类似结构,并始终选择专为该工作设计的工具,因为结构可能是不可预测的,并且您永远无法确定使用我提供的“hack”得到的结果。 但是,并不是所有事情都是黑白分明的,因此在不要求完全准确的情况下,上述就足够了。
The below snippet will covert majority of js~like structures into valid JSON syntax. While a little more extended than other answers the payoff is a more concise result. In situations where the parse cannot apply, we will fail gracefully, print the error to console and return the original input.
Example
Flems Playground
Capabilities
✓ Omits any trailing commas.
✓ Escapes newlines within strings.
✓ Handles array
[]
entries, converting alphanumeric occurences to strings.✓ Preserves boolean occurrences of
true
orfalse
.✓ Preserves
number
orfloat
occurrences.Code
Breakdown
Here is brief overview of what is happening:
true
andfalse
JSON.parse
Disclaimer
One should typically avoid converting string json~like structures with regex and always opt for a tool designed for the job because the structures can be unpredictable and you can never be certain of the result using the "hack" I've provided. However, not everything is black and white, as such in cases where complete accuracy is not demanded, the above will suffice.
“带有注释的 JSON”实际上是一个有效的 javascript,因此在 javascript 环境中,解析它的最简单的本机方法就是像这样评估它,
输出是
"JSON with comments" is actually a valid javascript, therefore in javascript environment the simplest native way to parse it is just evaluate it like this
Output is
!!!考虑安全风险——不要盲目评估
!!! considering security risks -- do not eval blindly