“ Object.fromEntries()”是否不受原型污染的影响?

时间:2020-08-17 16:30:11

标签: javascript security prototype exploit

考虑以下简单的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处理未经检查的用户提供的数据吗?

1 个答案:

答案 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.prototypehasOwnProperty

您会注意到isPrototypeOf确实构建了具有 own Object.fromEntries属性的对象,并且.__proto__(尽管仍然是x.__proto__ !== Object.prototype)。继承的属性被遮盖。