`Object.fromEntries()` 是否可以避免原型污染?
Is `Object.fromEntries()` secure from prototype pollution?
考虑以下 JavaScript 中原型污染的简单示例:
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
确实构建了一个具有 own .__proto__
属性 的对象,并且 x.__proto__ !== Object.prototype
(尽管仍然 Object.getPrototypeOf(x) === Object.prototype
)。继承的属性被遮蔽了
考虑以下 JavaScript 中原型污染的简单示例:
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
确实构建了一个具有 own .__proto__
属性 的对象,并且 x.__proto__ !== Object.prototype
(尽管仍然 Object.getPrototypeOf(x) === Object.prototype
)。继承的属性被遮蔽了