2 回答
TA贡献1815条经验 获得超13个赞
我主要担心的是原型污染
注意JSON.parse
不会污染任何原型对象。如果 JSON 字符串有一个"__proto__"
键,那么该键将像任何其他键一样被创建,无论该 JSON 中对应的值是什么,它最终都会作为该属性值,而不是在原型对象 () 中Object.prototype
。
风险在于您之后对该对象所做的操作。如果您执行(深)复制,使用属性分配 或Object.assign
,那么您可能会改变原型对象。
我们如何在运行前对其进行消毒
JSON.parse(untrustedString)
?...我认为可以通过正则表达式处理
不要为此使用正则表达式。使用 的第二个参数JSON.parse
:
const cleaner = (key, value) => key === "__proto__" ? undefined : value;
// demo
let json = '{"user":{"__proto__":{"admin": true}}}';
console.log(JSON.parse(json));
console.log(JSON.parse(json, cleaner));
TA贡献1794条经验 获得超7个赞
在你对它做任何事情之前,userString
它只是一个字符串,并且该字符串中的任何内容本身都不会损害系统,除非系统做一些事情来允许这种损害,比如以不安全的方式处理它。
输入JSON.parse()
。
JSON.parse()
只是一个格式转换工具。它不会从数据中运行任何方法(原型污染利用依赖于它),或者实际上什至查看包含在字符串化对象本身中的数据,除了它包含的结构语法和 JavaScript 保留字,用于验证目的(MDN polyfill例子)。与字符串相同的原则适用于此;如果您不对输出对象做任何不安全的事情,它就不会伤害您或您的系统。
归根结底,防止滥用归结为验证和安全数据处理实践:
检查解析字符串产生的对象,并在严格的参数范围内验证它,忽略原型突变。
使用
Object.prototype.hasOwnProperty.call()
。使用 eslint(no-prototype-builtins 规则)等工具在您的代码库中强制实施这些做法。不要指望用户发送完美、安全的数据。
在您链接的文章中,作者提到了这个确切的想法:
...来自用户的数据应始终进行过滤和清理。
添加回答
举报