@@toStringTag spoofing for null and undefined
Jordan Harband
ljharb at gmail.com
Wed Jan 28 16:29:00 PST 2015
To summarize the discussion at today's TC39 meeting:
Given that the style of checks that Allen proposed (
https://esdiscuss.org/topic/tostringtag-spoofing-for-null-and-undefined#content-59
) (using non-side-effecty non-generic methods that rely on internal slots,
in a try/catch) is indeed reliable in ES3, and will continue to be reliable
in ES6, any security-conscious code should update itself to use these kinds
of checks rather than an Object.prototype.toString.call check. v8 (and any
other implementations that are working on @@toStringTag) will leave
Symbol.toStringTag behind a flag for a full two months, to give the
relevant code time to release updates.
In addition, anybody who modifies a builtin so that, say, a Boolean reports
itself as a Number, surely intends the effects of this change, and so there
is no concern about them. In accordance with this, step 17b of
https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring
will be removed - if a developer wants to make a non-builtin value
masquerade as a builtin, they similarly are intending those effects.
I've updated and/or released the following npm packages to remain resilient
with respect to this change in case anyone wants some specific examples of
how to implement this:
- https://www.npmjs.com/package/is-equal
- https://www.npmjs.com/package/is-date-object
- https://www.npmjs.com/package/is-number-object
- https://www.npmjs.com/package/is-regex
- https://www.npmjs.com/package/is-symbol
In addition, I've closed and added similar comments to the spec bug I
originally filed: https://bugs.ecmascript.org/show_bug.cgi?id=3506
Thanks, everyone, for your thoughts and time!
- Jordan
On Sat, Jan 24, 2015 at 2:59 PM, Mark Miller <erights at gmail.com> wrote:
> Put better, the spec requires that Object.freeze(Object.prototype) works.
>
>
> On Sat, Jan 24, 2015 at 2:57 PM, Mark Miller <erights at gmail.com> wrote:
>
>>
>>
>> On Sat, Jan 24, 2015 at 2:42 PM, Isiah Meadows <impinball at gmail.com>
>> wrote:
>>
>>> > From: "Mark S. Miller" <erights at google.com>
>>> > To: Gary Guo <nbdd0121 at hotmail.com>
>>> > Cc: "es-discuss at mozilla.org" <es-discuss at mozilla.org>
>>> > Date: Sat, 24 Jan 2015 07:11:35 -0800
>>> > Subject: Re: @@toStringTag spoofing for null and undefined
>>> > Of course it can, by tamper proofing (essentially, freezing)
>>> Object.prototype. None of these protections are relevant anyway in an
>>> environment in which the primordials are not locked down.
>>>
>>> Yeah, pretty much. That proverbial inch was given a long time ago. And
>>> the proverbial mile taken. And I highly doubt the spec is going to require
>>> `Object.freeze(Object.prototype)`,
>>>
>> Of course not. The key is the spec allows it. SES makes use of that.
>>
>>
>>
>>
>>
>>> since that prohibits future polyfills and prolyfills of the Object
>>> prototype. Also, you could always straight up overwrite it, but that's even
>>> harder to protect against. (And how many cases do you know of literally
>>> overwriting built-in prototypes?)
>>>
>>> Or, to throw out an analog to Java, it is perfectly possible to call or
>>> even override a private method through reflection. JavaScript simply has
>>> more accessible reflection, more often useful since it's a more dynamic
>>> prototype-based OO language as opposed to a stricter class-based language.
>>>
>>> >
>>> > On Sat, Jan 24, 2015 at 6:11 AM, Gary Guo <nbdd0121 at hotmail.com>
>>> wrote:
>>> >>
>>> >> Now I have a tendency to support the suggestion that cuts the
>>> anti-spoofing part. If coder wants to make an object and pretend it's a
>>> built-in, let it be. The anti-spoofing algorithm could not prevent this
>>> case:
>>> >> ```
>>> >> Object.prototype.toString = function(){
>>> >> return '[object I_Can_Be_Anything]';
>>> >> }
>>> >> ```
>>> >>
>>>
>>> Or this:
>>> ```js
>>> function handler() {
>>> throw new Error("No prototype for you!");
>>> }
>>>
>>> Object.defineProperty(
>>> Object,
>>> 'prototype',
>>> {
>>> get: handler,
>>> set: handler,
>>> enumerable: true
>>> });
>>> ```
>>>
>>> Me thinks this isn't going to get "fixed".
>>>
>>> >> _______________________________________________
>>> >> es-discuss mailing list
>>> >> es-discuss at mozilla.org
>>> >> https://mail.mozilla.org/listinfo/es-discuss
>>> >>
>>> >
>>> >
>>> >
>>> > --
>>> > Cheers,
>>> > --MarkM
>>> >
>>> >
>>>
>>> _______________________________________________
>>> es-discuss mailing list
>>> es-discuss at mozilla.org
>>> https://mail.mozilla.org/listinfo/es-discuss
>>>
>>>
>>
>>
>> --
>> Text by me above is hereby placed in the public domain
>>
>> Cheers,
>> --MarkM
>>
>
>
>
> --
> Text by me above is hereby placed in the public domain
>
> Cheers,
> --MarkM
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150128/b8172303/attachment.html>
More information about the es-discuss
mailing list