安全地解析带有不带引号的键的 JSON 字符串

问题描述 投票:0回答:5

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 );
}
javascript json object-literal json5
5个回答
6
投票
data.replace(/(['"])?([a-zA-Z0-9]+)(['"])?:/g, '"$2":');

这将替换参数名称上的任何单引号,并添加任何缺少的单引号。


3
投票

使用
JSON5.parse

JSON5 是 JSON 的超集,允许 ES5 语法,包括 unquoted 属性键。 JSON5 参考实现(

json5
npm 包)提供了一个
JSON5
对象,该对象具有与内置
JSON
对象相同的方法以及相同的参数和语义。

JSON5 被许多知名项目使用:

JSON5 于 2012 年启动,截至 2022 年,每周下载量超过 6500 万次,在 npm 上最依赖的软件包中排名前 0.1%,并已被 Chromium、Next.js、 Babel、Retool、WebStorm 等等。 MacOS 和 iOS 等 Apple 平台也原生支持它。

~ json5.org 主页


1
投票

JSON 不允许不带引号的键。 JSON 是 JavaScript 表示法的子集,不包括不带引号的键。将不带引号的键传递给几乎任何 JSON 解析器都可能会抛出错误或返回“意外”结果。

希望这有帮助


-1
投票

“带有注释的 JSON”实际上是一个有效的 javascript,因此在 javascript 环境中解析它的最简单的本机方法就是像这样评估它

function evalJs(js) {
    let fn = new Function("return (" + js + ")"),
        res = fn()
    return res;
}

let json5 = "{\n" +
    "//////\n" +
    "key: 5," +
    "}"

let data = evalJs(json5)
console.info(data)

输出是

{ key: 5 }

-1
投票

!!!考虑安全风险——不要盲目评估

Object.defineProperty(String.prototype, "eval", {
    get: function() {
       let v;
       eval('v =' + this);
       return v;
    }
 });

var object = '{A:1,"B":[1,\'alfa\',"beta"]}'.eval 
© www.soinside.com 2019 - 2024. All rights reserved.