On Thu, Feb 19, 2015 at 10:14 AM, Andrea Giammarchi <
[email protected]> wrote:

> uhm ... have I forgotten a `delete` or should I have set `{value: 
> Object.prototype[name],
> writable: false, configurable: false}` instead ? (enumerable should be
> preserved as false too)
>

Either would work, but I would do the second. The first technique is not
idempotent but the second is. Deleting will fail a second time, but setting
a property to its current settings works fine.



>
> Yep, actually you got me there, this is a light side effect since usually
> nobody redefines the `Object.prototype`, but good to know, I could have
> fallen hard there.
>
> Cheers
>
> On Thu, Feb 19, 2015 at 6:06 PM, Mark S. Miller <[email protected]>
> wrote:
>
>>
>>
>> On Thu, Feb 19, 2015 at 9:54 AM, Andrea Giammarchi <
>> [email protected]> wrote:
>>
>>> Just as workaround, if you really need that much to freeze the
>>> `Object.prototype`, you could:
>>>
>>> ```js
>>> Object
>>>   .getOwnPropertyNames(Object.prototype)
>>>   .filter((name) => !/^constructor|toString|valueIOf$/.test(name))
>>>   .forEach((name) => Object.defineProperty(
>>>     Object.prototype,
>>>     name,
>>>     {value: Object.prototype[name]}
>>>   ))
>>>
>>
>>
>> Your defineProperty call above has no effect. When doing a defineProperty
>> on an existing property, recall that omitting attributes means that the
>> setting of these attributes should not be changed. Omitted attributes only
>> default to false when the property does not already exist.
>>
>> Interesting that I've seen this bug several times now, by several
>> different authors. Apparently, it is an unanticipated footgun in the ES5
>> reflection API.
>>
>>
>>
>>> ;
>>> Object.preventExtensions(Object.prototype);
>>> ```
>>>
>>> You can eventually fix those 3 properties somehow via accessors.
>>>
>>> Not ideal, but it should hopefully make your project work (at least)
>>>
>>> Best Regards
>>>
>>>
>>> On Thu, Feb 19, 2015 at 5:23 PM, David Bruant <[email protected]>
>>> wrote:
>>>
>>>> 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/6c5fe5be8cd01e0b4e91fa96d02534
>>>> 1aff1db291/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
>>>> _______________________________________________
>>>> es-discuss mailing list
>>>> [email protected]
>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>>
>>>
>>>
>>> _______________________________________________
>>> es-discuss mailing list
>>> [email protected]
>>> https://mail.mozilla.org/listinfo/es-discuss
>>>
>>>
>>
>>
>> --
>>     Cheers,
>>     --MarkM
>>
>
>


-- 
    Cheers,
    --MarkM
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to