消毒JSON是必要的吗?
我认为这是networking上一个众所周知的最佳做法,不相信任何input。 这句话
“所有的投入都是邪恶的。”
可能是inputvalidation方面引用最多的引用。 现在,对于HTML,您可以使用诸如DOMPurify之类的工具对其进行消毒。
我的问题是,如果我有一个运行Express和body-parser中间件的Node.js服务器来接收和parsingJSON,我是否还需要运行任何清理?
我的(也许天真?)的想法是,JSON只是数据,没有代码,如果有人发送无效的JSON,body-parser(内部使用JSON.parse()
)将失败,所以我知道我的应用程序将接收一个有效的JavaScript对象。 只要我不运行eval或调用函数,我应该没事,不是吗?
我错过了什么吗?
由于JSON.parse()
不运行任何代码,因此它不像eval()
那样易受攻击,但是仍然应该采取措施保护服务器和应用程序的完整性,例如:
-
JSON.parse()
可以引发exception,在适当的地方应用exception处理程序。 - 不要对有什么数据做出假设,在使用数据之前必须明确地testing数据。
- 只处理你正在寻找的属性(避免可能在JSON中的其他事情)。
- validation所有传入的数据是合法的,可接受的值。
- 消除数据的长度(以防止DOS数据量过大的问题)。
- 不要将这些传入的数据放到可以进一步评估的地方,例如直接进入页面的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的结果中接受的值