title: Is `Object.fromEntries()` secure from prototype pollution?
body: <p>Consider the following simple example of prototype pollution in JavaScript:</p>
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>function sayHello(name) {
    console.log(`Hi ${name}!`);
  }
  
  // Pollute the prototype
  ({}).__proto__.toString = () =&gt; alert('hacked');
  
  // Trigger the exploit
  sayHello({});</code></pre>
  </div>
  </div>
  </p>
  <p>I was wondering if a similar exploit could be done with <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries" rel="nofollow noreferrer"><code>Object.fromEntries</code></a>, so I tested:</p>
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>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: () =&gt; alert('hacked') }]]);
  
  // Try to trigger the exploit, but fail
  sayHello({}); // Hi [object Object]
  sayHello(x); // Hi [object Object]</code></pre>
  </div>
  </div>
  </p>
  <p>The fact that the built-in <code>Object.fromEntries</code> is safe from this exploit is great, I was expecting some protection. However, I thought it would either throw an error or skip setting the <code>__proto__</code>, but to my surprise the <code>__proto__</code> was actually set!</p>
  <pre><code>x.__proto__.toString(); // Exploited!
  x.toString(); // Not exploited!!
  </code></pre>
  <p>I was very surprised that <code>Object.fromEntries</code> managed to create an object whose <code>.__proto__.toString</code> is exploited while <code>.toString</code> is not.</p>
  <p>So, is this safe?</p>
  <p><strong>Can I use <code>Object.fromEntries</code> with unchecked user-supplied data safely?</strong></p>