考虑以下简单的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
处理未经检查的用户提供的数据吗?
答案 0 :(得分:1)
我可以安全地使用
[Unit] Description=Ethereum go client After=network.target Wants=network.target [Service] User=goeth Group=goeth Type=simple Restart=always RestartSec=5 ExecStart=geth --goerli --http **--ipcpath /var/lib/goethereum/geth.ipc** --datadir /mnt/t5/goethereum/ [Install] WantedBy=default.target
处理用户未提供的数据吗?
是的,它将永远不会通过构建对象来修改Object.fromEntries
。
Object.prototype
成功创建了一个对象,Object.fromEntries
被.__proto__.toString
未被利用,我感到非常惊讶。
这里.toString
没什么特别的,它只是.__proto__
上的getter / setter属性,类似于Object.prototype
或hasOwnProperty
。
您会注意到isPrototypeOf
确实构建了具有 own Object.fromEntries
属性的对象,并且.__proto__
(尽管仍然是x.__proto__ !== Object.prototype
)。继承的属性被遮盖。