https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring step 17b lists the following built in string tags:
"Arguments", "Array", "Boolean", "Date", "Error", "Function", "Number", "RegExp", or "String"
I understand that new things added in ES6 will not have the same protection for legacy purposes (that's a separate discussion) - but what about Math and JSON, both of which are in ES5 and might have the same legacy code checks?
Also, what about objects without a @@toStringTag specified, which return "[object Object]"?
In other words, it appears to me that "Math", "JSON", and "Object" should all be in this same unspoof-able list. Thoughts?
The built-in objects Math and JSON are regular ordinary objects that could be entirely reimplemented by user code. IMHO, there isn't much value in protecting such objects.
However, currently they can be brand-checked via Object.prototype.toString.call - isn't the purpose of this protection to ensure that such brand-checking never breaks?
However, we'd have to add some sort of branding internal slot to Math and JSON in order to do this.
How likely to you think that anybody is actually brand checking Math and JSON using O.p.toString. It seems pointless as it doesn't guarantee anything about the their properties.
I'm inclined to forgo the added complexity and see if this slip by.
For completeness, among the tags defined before ES6, there is also "Undefined" and "Null".
(Not that I'd like to protect those any more than "JSON", etc.)
To summarize the discussion at today's TC39 meeting:
Given that the style of checks that Allen proposed (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, 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.