在 JavaScript 对象上分配哪些键是不安全的(例如 '__proto__')?



我想使用JavaScript对象({}(作为字典来存储不受信任的数据。(我知道有Map,但假设我不想使用Map

如果我写

let obj = {};
obj[key] = value;

如果keyvalue由不受信任的来源提供,哪些密钥会导致令人惊讶的行为?

我知道分配obj.__proto__可以更改对象的原型,从而更改对象的行为。(这有时被称为原型中毒。所以我可能应该排除'__proto__'

let obj = {};
if (key !== '__proto__') {
obj[key] = value;
}

是否有其他此类不安全键可以以某种方式更改对象的行为,还是'__proto__'唯一的键?

如果您引用 ECMAScript 规范或参考文档,则可以获得奖励积分。

Object.prototype上的所有属性都可能导致有问题的名称冲突:

console.log(
Object.getOwnPropertyNames(Object.prototype)
);

就是这样。

避免担心名称冲突的另一种选择是创建一个继承自Object.prototype的对象,例如:

const obj = Object.create(null);
// Now, this is perfectly fine (though weird):
obj.__proto__ = 'foo';
console.log(obj.__proto__);

如果您只是想从原型中排除现有值,则可以使用两个检查的组合:

1(他们尝试设置的属性是否已经存在于对象中:

const exists = '__proto__' in obj; // Or whichever property name they are setting

2(如果是这样,它是直接属性,还是来自上游(例如,您可以允许他们设置/覆盖他们之前直接在对象上设置的现有属性(。

const onSelf = obj.hasOwnProperty('__proto__'); // Or whichever property name they are setting

那么也许您的保护看起来像:

if (!(key in obj) || obj.hasOwnProperty(key)) {
obj[key] = value;
}

看:

  • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty
  • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in

最新更新