B.3.1 The __proto__ pseudo property

Andrea Giammarchi andrea.giammarchi at gmail.com
Sun Apr 21 22:08:49 PDT 2013


oh dear ...

var protoSetter = Object.getOwnPropertyDescriptor(
  Object.prototype, '__proto__'
).set; // <==== forgot the setter in previous example


On Sun, Apr 21, 2013 at 10:07 PM, Andrea Giammarchi <
andrea.giammarchi at gmail.com> wrote:

> right now this is the V8 situation:
> https://code.google.com/p/v8/issues/detail?id=2645
>
> which is different from SpiderMonkey one where you can:
>
> var protoSetter = Object.getOwnPropertyDescriptor(
>   Object.prototype, '__proto__'
> );
> delete Object.prototype.__proto__; // optionally
>
> var a = {}, b = {};
> protoSetter.call(a, b);
> b.isPrototypeOf(a); // true
>
> Which makes the "magic" of the __proto__ available.
> Otherwise it does not make sense to have it configurable but unusable
> because in some very specific case that setter might be needed, as it is
> now, mostly to promote NodeList collections into something else (the Zepto
> case)
>
> I don't think Zepto should change (apparently it won't in any case) but I
> don't think for that single, very specific, case, the whole environment
> should be exposed to __proto__.
>
> In SES case, you could poison upfront getOwnpropertyDescriptor on SES side
> instead of expecting a poisoned thing from native V8 as __proto__
> descriptor and it's setter.
>
> The patch I've linked and proposed makes that setter available, but this
> should, in my opinion, be the standard behavior, so that is possible to
> drop the __proto__ and reuse in those very few little edge cases.
>
> Is this any more clear? Thanks for your patience, it's clearly hard for me
> to express myself in your own terms.
>
> Regards
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> On Sun, Apr 21, 2013 at 9:59 PM, Mark S. Miller <erights at google.com>wrote:
>
>> On Sun, Apr 21, 2013 at 9:56 PM, Andrea Giammarchi <
>> andrea.giammarchi at gmail.com> wrote:
>>
>>> if Object.getPrototypeOf() works there, how is that secret protected?
>>>
>>
>> Assuming the script does not make the object that the literal evaluates
>> to available to the hostile environment it is running it. This was always
>> the delicate assumption of the old argument.
>>
>>
>>
>>
>>>
>>> In any case, do you agree since you can configure
>>> Object.prototype.__proto__ you could also poison it by your own instead of
>>> proposing an unusable poisoned setter as it is now in V8?
>>>
>>> I am talking about this possibility (already in Firefox):
>>>
>>> var set = Object.getOwnPropertyDescriptor(
>>>       Object.prototype,
>>>       '__proto__'
>>>     ).set;
>>>
>>> delete Object.prototype.__proto__;
>>>
>>> together with this for, eventually, SES
>>>
>>> (function(getOwnPropertyDescriptor){
>>>   Object.defineProperty(
>>>     Object,
>>>     'getOwnPropertyDescriptor',
>>>     {
>>>       enumerable: false,
>>>       configurable: false,
>>>       writable: false,
>>>       value: function(object, property) {
>>>         var d = getOwnPropertyDescriptor(object, property);
>>>         if (d && property === '__proto__') {
>>>           d.set = function () {
>>>             throw new Error('nope');
>>>           };
>>>         }
>>>       }
>>>     }
>>>   );
>>> }(Object.getOwnPropertyDescriptor));
>>>
>>> So that whoever want to delete can reuse same "magic" and work in a
>>> __proto__ free environment, literals special syntax a part (don't care
>>> much, equivalent shortcut of Object.create() so it's OK)
>>>
>>> What do you think?
>>>
>>
>>
>> I'm sorry, I don't get the point. What are you trying to demonstrate?
>>
>>
>>
>>
>>>
>>>
>>>
>>> On Sun, Apr 21, 2013 at 9:43 PM, Mark S. Miller <erights at google.com>wrote:
>>>
>>>> On Sun, Apr 21, 2013 at 8:45 PM, Brendan Eich <brendan at mozilla.com>wrote:
>>>>
>>>>> Andrea may be asking for less than the standard someday removing
>>>>> __proto__, if I read him right. He's asking not to keep it
>>>>> "indestructible", i.e., to make
>>>>>
>>>>>   delete Object.prototype.__proto__
>>>>>
>>>>> remove all the magic, including for 'o = {__proto__: p}'.
>>>>>
>>>>
>>>> Andrea, my apologies. I jumped into this thread in the middle and
>>>> misinterpreted. I still don't like that idea, but not on the grounds
>>>> previously stated.
>>>>
>>>>
>>>>
>>>>
>>>>>
>>>>> But that seems to require using [[Put]] rather than
>>>>> [[SetInheritance]], and you said that's a security problem. Could you show
>>>>> how? I asked in my immediately preceding message how creating custom
>>>>> proto-chains for guaranteed fresh objects via literals makes trouble for
>>>>> SES.
>>>>>
>>>>
>>>>
>>>> I truly hate to make any security argument whatsoever based on the Same
>>>> Origin Policy (SOP). However, one of the legacy constraints of the web we
>>>> must respect is not to break security that was successfully built on the
>>>> SOP, even if the form of security at stake was a twisted miserable affair.
>>>> I agree that we should generally respect this constraint.
>>>>
>>>> An old argument about the safety of having <script> tags do cross
>>>> origin HTTP GETs without any special arrangement is that the requesting
>>>> page could not *read* information contained in the script unless the
>>>> script's behavior intends to reveal that information. I think this
>>>> rationale was silly, as the script is being loaded into a potentially
>>>> hostile environment that can already cause the script to behave in ways
>>>> very different from its author's intentions. The counter-argument was that,
>>>> at least literals themselves are safe. The counter-counter argument,
>>>> presented as a vulnerability demonstrated by an attack (citation anyone?),
>>>> is that on browsers with getters and setters, the ES3
>>>> literal-invokes-[[Put]] behavior enables the requestor to steal even
>>>> information within JS literals. The argument should have stopped there,
>>>> with the defenders of the SOP conceding that script tags allow cross origin
>>>> reads with no further protection.
>>>>
>>>> Instead, this continued to be seen as a meaningful vulnerability to be
>>>> fixed. ES5 fixed this vulnerability regarding literals. In my opinion, I
>>>> think this fix creates only confusion and a false sense of security. The
>>>> script as a whole is still being loaded into a hostile environment, and it
>>>> is not realistic to expect programmers to write interesting scripts that
>>>> keep secrets when running in that environment. But I know of no way to get
>>>> the advocates of the SOP to stop. Witness the recent agreement, without
>>>> dissent, that a cross-origin module-source GET where the module loader is
>>>> parameterized with the translate hook should require the special UMP/CORS
>>>> permission. Whereas a cross-origin module-source GET without a translate
>>>> hook does not need this permission.
>>>>
>>>> Given that we are stuck with this as the explanation of browser
>>>> security constraints, we at least need a simple line between what is and is
>>>> not directly protected. With ES5 the line is "literals". This is simpler to
>>>> understand than "literals that don't use the special __proto__ syntax." If
>>>> programmers rely on this simpler explanation, the following literal should
>>>> still be able to protect its secrets when loaded into a hostile environment:
>>>>
>>>>     { __proto__: { secret: "857234850349859234" }}
>>>>
>>>> My preference is that we get the world of the web to admit that there
>>>> is no meaningful protection of a script's secrets from its loading
>>>> environment. But I am not hopeful. In the absence of this agreement, we
>>>> must not break the supposed security vulnerability that the web thinks we
>>>> fixed in ES5. And so long as programmers are encouraged to count on this
>>>> protection, we must not make the explanation of the delicate property they
>>>> are counting on more complex than they will accurately remember.
>>>>
>>>> The process of writing this down makes me even more aware of how
>>>> convoluted it is. I retract my statement that "This is a big deal." I could
>>>> probably be argued out of it if there was something significant to be
>>>> gained. In this case, I don't think there is.
>>>>
>>>>
>>>>
>>>>>
>>>>> /be
>>>>>
>>>>> Mark Miller wrote:
>>>>>
>>>>>> Hi Andrea, Allen's immediately previous sentence was
>>>>>>
>>>>>> "The point is that I don't think there is any long standing behavior
>>>>>> in this regard relating to object literals and deleting
>>>>>> Object.prototype.__proto__ that the web is dependent upon."
>>>>>>
>>>>>> This sets the context for understanding Allen's next sentence. We are
>>>>>> constrained by cross-browser legacy. So long as IE was not planning to
>>>>>> implement __proto__, we avoided standardizing it. In the current situation,
>>>>>> TC39 is powerless to prevent __proto__ becoming a cross-browser standard.
>>>>>> Our only choices are
>>>>>>
>>>>>> 1) We design and codify a spec that all these browsers can agree on,
>>>>>> that does not break existing cross-browser (IE aside) web content, and that
>>>>>> is as clean as possible *within* those constraints.
>>>>>> 2) We do not do so, in which case each browser gropes separately to
>>>>>> be compatible enough with what the other browsers seem to be doing.
>>>>>>
>>>>>> And example of the consequences of #2 is the wildly different and
>>>>>> often bizarre semantics of block nested functions. This was the consequence
>>>>>> of omitting these from "official" JavaScript in a social/political context
>>>>>> where all browsers felt compelled to implement them anyway. They groped
>>>>>> towards compatibility without coordination and arrived at painfully
>>>>>> incoherent results. (Fortunately, we were able to quarantine this
>>>>>> bizarreness to sloppy mode.)
>>>>>>
>>>>>> As a standards committee, we need to be realistic about when we can
>>>>>> exercise normative power and when we can't. I'll even agree that, when
>>>>>> we're uncertain, we should err on the side of cleaning things up. Until IE
>>>>>> changed expectation, we were doing exactly that by avoiding __proto__.
>>>>>> Today, we no longer have that happy uncertainty.
>>>>>>
>>>>>>
>>>>>>
>>>>>> On Sun, Apr 21, 2013 at 6:47 PM, Andrea Giammarchi <
>>>>>> andrea.giammarchi at gmail.com <mailto:andrea.giammarchi@**gmail.com<andrea.giammarchi at gmail.com>>>
>>>>>> wrote:
>>>>>>
>>>>>>     On Sun, Apr 21, 2013 at 6:11 PM, Allen Wirfs-Brock
>>>>>>     <allen at wirfs-brock.com <mailto:allen at wirfs-brock.com>**> wrote:
>>>>>>
>>>>>>         We are free to specify a semantics that will make sense, now
>>>>>>         and for the long term.
>>>>>>
>>>>>>
>>>>>>     then, for the long term, if all I understood about this thing is
>>>>>>     that stinks for everybody, you should really consider to give
>>>>>>     developers the possibility to get rid of this property completely,
>>>>>>     if desired, instead of making it indestructible, IMHO
>>>>>>
>>>>>>
>>>>>>     ______________________________**_________________
>>>>>>     es-discuss mailing list
>>>>>>     es-discuss at mozilla.org <mailto:es-discuss at mozilla.org**>
>>>>>>
>>>>>>     https://mail.mozilla.org/**listinfo/es-discuss<https://mail.mozilla.org/listinfo/es-discuss>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> 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<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
>>>>
>>>>
>>>
>>
>>
>> --
>>     Cheers,
>>     --MarkM
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20130421/6a0aaeaa/attachment-0001.html>


More information about the es-discuss mailing list