考虑以下 JavaScript 中原型(prototype)污染的简单示例:
function sayHello(name) {
console.log(`Hi ${name}!`);
}
// Pollute the prototype
({}).__proto__.toString = () => alert('hacked');
// Trigger the exploit
sayHello({});
我想知道是否可以使用 Object.fromEntries
来完成类似的利用,所以我测试了:
function sayHello(name) {
console.log(`Hi ${name}!`);
}
// Try to pollute the prototype, but doesn't work, even for the same object!
const x = Object.fromEntries([['__proto__', { toString: () => alert('hacked') }]]);
// Try to trigger the exploit, but fail
sayHello({}); // Hi [object Object]
sayHello(x); // Hi [object Object]
事实上,内置的Object.fromEntries
可以安全地免受此漏洞利用,这一点很好,我期待一些保护。然而,我认为它要么抛出错误,要么跳过设置 __proto__
,但令我惊讶的是 __proto__
实际上已设置!
x.__proto__.toString(); // Exploited!
x.toString(); // Not exploited!!
令我感到非常惊讶的是,Object.fromEntries
成功创建了一个对象,其 .__proto__.toString
被利用,而 .toString
则未被利用。
那么,这安全吗?
我可以安全地将 Object.fromEntries
与未经检查的用户提供的数据一起使用吗?
最佳答案
Can I use
Object.fromEntries
with unchecked user-supplied data safely?
是的,它永远不会通过构建对象来修改Object.prototype
。
I was very surprised that
Object.fromEntries
managed to create an object whose.__proto__.toString
is exploited while.toString
is not.
这里的.__proto__
没有什么特别的,它只是Object.prototype
上的一个getter/setter属性,类似于hasOwnProperty
或isPrototypeOf
.
您会注意到 Object.fromEntries
确实使用自己的 .__proto__
属性构建了一个对象,并且 x.__proto__ !== Object.prototype
(尽管仍然是 Object.getPrototypeOf(x) === Object.prototype
)。继承的属性被隐藏。
关于javascript - `Object.fromEntries()` 是否免受原型(prototype)污染?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63454948/