David Bruant (2015-02-19T17:23:54.000Z)
Hi,

Half a million times the following meta-exchange happened on es-discuss:
- if an attacker modifies Object.prototype, then you're doomed in all 
sorts of ways
- Don't let anyone modify it. Just do Object.freeze(Object.prototype)!

I've done it on client-side projects with reasonable success. I've just 
tried on a Node project and lots of dependencies started throwing 
errors. (I imagine the difference is that in Node, it's easy to create 
projects with a big tree of dependencies which I haven't done too much 
on the client side).

I tracked down a few of these errors and they all seem to relate to the 
override mistake [1].
* In jsdom [2], trying to add a "constructor" property to an object 
fails because Object.prototype.constructor is configurable: false, 
writable: false
* in tough-cookie [3] (which is a dependency of the popular 'request' 
module), trying to set Cookie.prototype.toString fails because 
Object.prototype.toString is configurable: false, writable: false

Arguably, they could use Object.defineProperty, but they won't because 
it's less natural and it'd be absurd to try to fix npm. The 
Cookie.prototype.toString case is interesting. Of all the methods being 
added, only toString causes a problem. Using Object.defineProperty for 
this one would be an awkward inconsistency.


So, we're in a state where no module needs to modify Object.prototype, 
but I cannot freeze it because the override mistake makes throw any 
script that tries to set a toString property to an object.
Because of the override mistake, either I have to let Object.prototype 
mutable (depite no module needing it to be mutable) or freeze it first 
hand and not use popular modules like jsdom or request.

It's obviously possible to replace all built-in props by accessors [4], 
of course, but this is a bit ridiculous.
Can the override mistake be fixed? I imagine no web compat issues would 
occur since this change is about throwing less errors.

David

[1] http://wiki.ecmascript.org/doku.php?id=strawman:fixing_override_mistake
[2] 
https://github.com/tmpvar/jsdom/blob/6c5fe5be8cd01e0b4e91fa96d025341aff1db291/lib/jsdom/utils.js#L65-L95
[3] 
https://github.com/goinstant/tough-cookie/blob/c66bebadd634f4ff5d8a06519f9e0e4744986ab8/lib/cookie.js#L694
[4] 
https://github.com/rwaldron/tc39-notes/blob/c61f48cea5f2339a1ec65ca89827c8cff170779b/es6/2012-07/july-25.md#fix-override-mistake-aka-the-can-put-check
d at domenic.me (2015-02-22T03:28:33.774Z)
Half a million times the following meta-exchange happened on es-discuss:
- if an attacker modifies Object.prototype, then you're doomed in all 
sorts of ways
- Don't let anyone modify it. Just do Object.freeze(Object.prototype)!

I've done it on client-side projects with reasonable success. I've just 
tried on a Node project and lots of dependencies started throwing 
errors. (I imagine the difference is that in Node, it's easy to create 
projects with a big tree of dependencies which I haven't done too much 
on the client side).

I tracked down a few of these errors and they all seem to relate to [the 
override mistake][1].
* [In jsdom][2], trying to add a "constructor" property to an object 
fails because Object.prototype.constructor is configurable: false, 
writable: false
* [in tough-cookie][3] (which is a dependency of the popular 'request' 
module), trying to set Cookie.prototype.toString fails because 
Object.prototype.toString is configurable: false, writable: false

Arguably, they could use Object.defineProperty, but they won't because 
it's less natural and it'd be absurd to try to fix npm. The 
Cookie.prototype.toString case is interesting. Of all the methods being 
added, only toString causes a problem. Using Object.defineProperty for 
this one would be an awkward inconsistency.


So, we're in a state where no module needs to modify Object.prototype, 
but I cannot freeze it because the override mistake makes throw any 
script that tries to set a toString property to an object.
Because of the override mistake, either I have to let Object.prototype 
mutable (depite no module needing it to be mutable) or freeze it first 
hand and not use popular modules like jsdom or request.

It's obviously possible to [replace all built-in props by accessors][4], 
of course, but this is a bit ridiculous.
Can the override mistake be fixed? I imagine no web compat issues would 
occur since this change is about throwing less errors.

[1]: http://wiki.ecmascript.org/doku.php?id=strawman:fixing_override_mistake
[2]: https://github.com/tmpvar/jsdom/blob/6c5fe5be8cd01e0b4e91fa96d025341aff1db291/lib/jsdom/utils.js#L65-L95
[3]: https://github.com/goinstant/tough-cookie/blob/c66bebadd634f4ff5d8a06519f9e0e4744986ab8/lib/cookie.js#L694
[4]: https://github.com/rwaldron/tc39-notes/blob/c61f48cea5f2339a1ec65ca89827c8cff170779b/es6/2012-07/july-25.md#fix-override-mistake-aka-the-can-put-check