在一个JavaScript对象(例如'__proto__')上赋值哪些键是不安全的?

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

我想使用一个JavaScript对象({})作为一个字典来存储不受信任的数据。(我知道有一个 Map但如果说我不想使用 Map.)

如果我写

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

哪儿 keyvalue 是由一个不受信任的来源提供的,什么键会导致令人惊讶的行为?

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

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

是否还有其他这样的不安全键,可以以某种方式改变对象的行为,或者说是否有其他的不安全键?'__proto__' 唯一的一个?

如果你引用ECMAScript规范或参考文档,就会得到奖励。

javascript security
1个回答
3
投票

上的所有属性 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
投票

如果你只是简单地从原型中寻找排除现存的值,你可以使用两个检查的组合:

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;
}

参见:

© www.soinside.com 2019 - 2024. All rights reserved.