消毒JSON是必要的吗?

我认为这是networking上一个众所周知的最佳做法,不相信任何input。 这句话

“所有的投入都是邪恶的。”

可能是inputvalidation方面引用最多的引用。 现在,对于HTML,您可以使用诸如DOMPurify之类的工具对其进行消毒。

我的问题是,如果我有一个运行Express和body-parser中间件的Node.js服务器来接收和parsingJSON,我是否还需要运行任何清理?

我的(也许天真?)的想法是,JSON只是数据,没有代码,如果有人发送无效的JSON,body-parser(内部使用JSON.parse() )将失败,所以我知道我的应用程序将接收一个有效的JavaScript对象。 只要我不运行eval或调用函数,我应该没事,不是吗?

我错过了什么吗?

由于JSON.parse()不运行任何代码,因此它不像eval()那样易受攻击,但是仍然应该采取措施保护服务器和应用程序的完整性,例如:

  1. JSON.parse()可以引发exception,在适当的地方应用exception处理程序。
  2. 不要对有什么数据做出假设,在使用数据之前必须明确地testing数据。
  3. 只处理你正在寻找的属性(避免可能在JSON中的其他事情)。
  4. validation所有传入的数据是合法的,可接受的值。
  5. 消除数据的长度(以防止DOS数据量过大的问题)。
  6. 不要将这些传入的数据放到可以进一步评估的地方,例如直接进入页面的HTML或者直接注入到SQL语句中,而不进行进一步的清理,以确保对于该环境是安全的。

所以,要直接回答你的问题,“是”,除了使用body-parser之外还有更多的事情要做,尽pipe它是第一个处理数据的完美的前线。 一旦你从body-parser中得到数据,接下来要做的事情在很多情况下都很重要,并且需要特别小心。


作为一个例子,下面是一个parsing函数,期望一个对象具有应用这些检查的一些属性,并给你一个过滤的结果,只包含你所期望的属性:

 // pass expected list of properties and optional maxLen // returns obj or null function safeJSONParse(str, propArray, maxLen) { var parsedObj, safeObj = {}; try { if (maxLen && str.length > maxLen) { return null; } else { parsedObj = JSON.parse(str); if (typeof parsedObj !== "object" || Array.isArray(parsedObj)) { safeObj = parseObj; } else { // copy only expected properties to the safeObj propArray.forEach(function(prop) { if (parsedObj.hasOwnProperty(prop)) { safeObj[prop] = parseObj[prop]; } }); } return safeObj; } } catch(e) { return null; } } 

你应该没问题。 早期的JSON用户通常会在接收到的string上调用eval(),这当然是一个巨大的安全漏洞。 但是,正如你所说的,JSON.parse处理了大多数这种完整性检查。

只要你确保不会从收到的JSON对象中拿出某些东西,并将其直接传递给一个sql查询,例如,你应该没问题。

只要你使用JSON.parse将不会评估代码

尽pipe如此,您仍然应该将任何键:值对的白名单都列入要从parsing的结果中接受的值